2014-01-28 6 views
4

Я реализовал простой ThreadPool, который использует список std::list<Tasks> mTasks для списка задач.Что может проснуться условной переменной

Все нити ждет на условной переменной, используя следующий код:

EnterCriticalSection(&mCriticalSection); 

while(mTasks.size() ==0) 
    SleepConditionVariableCS(&mConditionVariable,&mCriticalSection, INFINITE); 

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

Я использовал некоторое время, проверяя, что список задач не пуст, хотя единственный способ пробудиться - это добавить новую задачу в список (поэтому он не может быть пустым), причина, по которой я это сделал потому что в MSDN написано:

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

Но что это за побочные пробуждения, что будет просыпать мою переменную?

+0

Здесь также должна работать блокировка-очередь-логика. – Nawaz

+0

Я добавил тэг 'winapi', однако ложные пробуждения происходят и на других ОС. – icabod

+0

@Nawaz Я не понял ваш комментарий – OopsUser

ответ

2

Мое понимание по этой теме, в то время, когда я изучала ее в университете, заключалось в том, что для реализации 100% -ных безопасных переменных состояния было бы слишком дорого с точки зрения производительности.

Википедию страница о spurious wakeups имеет цитату из Дэвида Р. Butenhof (автор Programming with POSIX Threads) говорила:

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

Проверкой состояния в while цикле является хорошей практикой, которая, безусловно, избежать этой проблемы.

Что касается более подробной информации о том, почему это действительно может произойти, извините, но я не могу представить такую ​​информацию.

1

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

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

Смежные вопросы