Форум программистов, компьютерный форум CyberForum.ru

C++

Войти
Регистрация
Восстановить пароль
 
elch10
38 / 21 / 4
Регистрация: 27.04.2015
Сообщений: 164
Завершенные тесты: 2
#1

Блокировка с двойной проверкой. Потоки - C++

31.05.2015, 09:07. Просмотров 407. Ответов 2
Метки нет (Все метки)

Цитата Сообщение от Mr. Hat Посмотреть сообщение
В учебнике Энтони Уильямса "Параллельное программирование на C++" описана проблема при использовании блокировки с двойной проверкой (Double-Checked Locking), из-за которой в стандарт C++11 ввели функцию std::call_once. Не могу понять ее суть. А объясняется она на таком примере:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
std::shared_ptr<some_resource> resource_ptr;
std::mutex resource_mutex;
void undefined_behaviour_with_double_checked_locking()
{
   if(!resource_ptr)  (1)
   {
       std::lock_guard<std::mutex> lk(resource_mutex);
       if(!resource_ptr) (2)
       {
            resource_ptr.reset(new some_resource);
       }
   }
   resource_ptr->do_something();  (3)
}
В книге написано: "...возникает гонка, угрожающая не самому указателю, а объекту, на который он указывает; даже если один поток видит, что указатель инициализирован другим потоком, он может не увидеть вновь созданного объекта some_resource, и, следовательно, вызов do_something() будет применен не к тому объекту..."
Та же самая проблема! Ведь этот код должен работать, объясняю почему: если указатель нулевой, то он не инициализирован, тогда захватывается мьютекс и происходит инициализация. Если в данный момент работает другой поток то он может не заметить, что указатель инициализирован в проверке (1), но тогда он будет ждать пока мьютекс освободится от 1 потока. После того как мьютекс освободился 2 поток может продолжить свою работу, но тогда указатель будет уже инициализирован, и проверка (2) уже никогда не будет true, то есть проверка(2) получит false и код внутри проверки (2) не выполнится, далее произойдёт освобождение мьютекса и выход из проверки (1), после чего вызовется функция do_something(). Какая может здесь быть проблема?
Лучшие ответы (1)
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
31.05.2015, 09:07
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Блокировка с двойной проверкой. Потоки (C++):

Текстовый редактор с проверкой орфографии - C++ Builder
Помогите наити проект текст редактора с проверкой орфографии. Может кто нибудь делал?!

Нужна помошь с проверкой 2 программ и решением одной. - C++ Builder
Есть 3 задачи очень нужно решить до вторника :wall:Помогите кто чем может... 1)Нужно решить массив.Размер массива 14,тип данных...

Многопоточность, блокировка с двойной проверкой - C++
Всем привет! Читаю книгу по многопоточности: &quot;...будет применен не к тому объекту что нужно&quot; - из этого можно сделать вывод что,...

Что такое потоки ввода, потоки вывода? - C++
Здарова всем! Не так давно уже прогаю на С++ и все НИКАК не могу понять, что такое потоки ввода, потоки вывода..! вот допустим...

Цикл с проверкой - C++
Здраствуйте. Пишу крестики\нолики в консоле,и вобщем возникла проблема с проверкой. do { cin &gt;&gt; Kletka; sGame(Kletka); ...

Цикл с проверкой isdigit - C++
Друзья, подскажите - есть такой код void main() { setlocale(LC_ALL, &quot;rus&quot;); int i=0; for (;;) { cin &gt;&gt;...

Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
gray_fox
What a waste!
1506 / 1209 / 68
Регистрация: 21.04.2012
Сообщений: 2,544
Завершенные тесты: 3
31.05.2015, 17:12 #2
Сообщение было отмечено автором темы, экспертом или модератором как ответ
Цитата Сообщение от elch10 Посмотреть сообщение
Какая может здесь быть проблема?
Цитата Сообщение от elch10 Посмотреть сообщение
C++
1
resource_ptr.reset(new some_resource);
Instruction reordering. Компилятор например может представить это так: (2.1) выделение памяти (2.2) вызов reset(...) (2.3) вызов конструктора some_resource. Тогда возможен такой сценарий: 1-й поток выделил память и инициализировал указатель (2.1 - 2.2), но объект ещё не сконструирован; 2-й поток видит уже инициализированный указатель resource_ptr (1) и использует "не до конца созданный" объект (3).
elch10
38 / 21 / 4
Регистрация: 27.04.2015
Сообщений: 164
Завершенные тесты: 2
01.06.2015, 12:15  [ТС] #3
Спасибо большое!
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
01.06.2015, 12:15
Привет! Вот еще темы с ответами:

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

Двумерный массив с проверкой условий - C++
1)Нужно задать одномерный массив и заполнить его значениями. Размер массива 168 значений. 2)Проверить эти значения на условие. Среднее...

Проблемы с проверкой введённых данных - C++
Никак не могу раобраться с проверкой на ввод числа, символа Которую нужно обязательно добавить Помогите пожалуйста :cry: :sorry: ...

проблема с проверкой вводимых данных - C++
#include &lt;iostream&gt; #include &lt;conio.h&gt; using namespace std; double c,f; int main() { setlocale(LC_ALL, &quot;Russian&quot;); ...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru