Многопоточность. Нужны ли критические разделы для доступа только для чтения?

У меня есть куча потоков. Они должны получить доступ к синглтону, содержащему данные конфигурации, который инициализируется один раз при создании синглтона. Отсюда и первый доступ. Поэтому дальнейшие действия над синглтоном доступны только для чтения. Нужны ли критические разделы в этом случае?

5

Решение

Похоже, потому что данные созданы лениво при первом обращении указатель или ссылка на ваш синглтон будет доступен для чтения и записи. Это означает, что вам нужен критический раздел.

На самом деле, желание избежать критической секции, сохраняя ленивую инициализацию в этой ситуации, было настолько повсеместно сильным, что это привело к созданию двойная проверка блокировки антипаттерна.

С другой стороны, если вы должны были инициализировать свой синглтон с нетерпением перед чтением вы сможете избежать критической секции для доступа к неизменяемому объекту через постоянный указатель / ссылку.

4

Другие решения

Я понимаю ваш вопрос, так как в вашем синглтоне есть ленивая инициализация. Инициализируется только для первого чтения.

Следующие последовательные чтения являются потокобезопасными. Но как насчет одновременного чтения во время инициализации?

Если у вас есть такая ситуация:

SomeConfig& SomeConfig::getInstance()
{
static SomeConfig instance;
return instance;
}

Тогда это зависит от вашего компилятора. Согласно этому сообщение в C ++ 03 это зависит от реализации, если эта статическая инициализация является поточно-ориентированной.

Для C ++ 11 это потокобезопасно — см. Ответы на это сообщение, цитата:

такая переменная инициализируется при первом прохождении контроля через ее объявление; такая переменная считается инициализированной по завершении ее инициализации. […] Если элемент управления вводит объявление одновременно во время инициализации переменной, параллельное выполнение должно ожидать завершения инициализации.

Стоит отметить, что доступ только для чтения к глобальным переменным является потокобезопасным.

1

Нет. Если вы просто читаете эти данные после полной инициализации и данные никогда не меняется тогда нет возможности возникновения состояния гонки.

Однако, если данные записываются / изменяются каким-либо образом, вам необходимо синхронизировать доступ к ним, т.е. заблокировать данные перед записью.

0

Если вы когда-либо читаете только некоторые общие данные и никогда не пишете, вам не нужно синхронизировать доступ.

Синхронизировать нужно только тогда, когда совместно используемый фрагмент данных одновременно читается и записывается.

0

Официальное правило в спецификации состоит в том, что гонка данных — это когда один поток может одновременно записывать в переменную, а другой поток читает или записывает одну и ту же переменную.

Если вы можете доказать, что инициализация должна произойти до того, как кто-либо из читателей сможет прочитать, синхронизация не требуется. Чаще всего это достигается инициализацией перед созданием (или синхронизацией) потоков или использованием статических переменных хранения, которые C ++ 11 гарантирует некоторую синхронизацию при

0
По вопросам рекламы ammmcru@yandex.ru
Adblock
detector