Внезапно оказалось, что я не вполне понимаю спецификацию автоматического Event в Windows.
Вот что в ней написано:
http://msdn.microsoft.com/en-us/library/windows/desktop/ms682655(v=vs.85).aspx
Auto-reset event
An event object whose state remains signaled until a single waiting thread is released, at which time the system automatically sets the state to nonsignaled.
If no threads are waiting, the event object's state remains signaled. If more than one thread is waiting, a waiting thread is selected. Do not assume a first-in, first-out (FIFO) order. External events such as kernel-mode APCs can change the wait order.
Из этого описания мне несколько непонятно, можно ли просигналить Event, а ЗАТЕМ тем же тредом дождаться этого Event-a, если одновременно в наличии другие треды, уже ждущие данный Event?
Если же кто-то процитирует "a waiting thread is selected" как свидетельство того, что выбирается всё же один из уже ждущих тредов, я спрошу иначе:
если есть несколько ждущих тредов и два треда одновременно вызывают SetEvent, есть ли гарантия, что разблокируются два ждущих треда, или такой гарантии всё же нет и один из SetEvent может потеряться?
Вот что в ней написано:
http://msdn.microsoft.com/en-us/library/windows/desktop/ms682655(v=vs.85).aspx
Auto-reset event
An event object whose state remains signaled until a single waiting thread is released, at which time the system automatically sets the state to nonsignaled.
If no threads are waiting, the event object's state remains signaled. If more than one thread is waiting, a waiting thread is selected. Do not assume a first-in, first-out (FIFO) order. External events such as kernel-mode APCs can change the wait order.
Из этого описания мне несколько непонятно, можно ли просигналить Event, а ЗАТЕМ тем же тредом дождаться этого Event-a, если одновременно в наличии другие треды, уже ждущие данный Event?
Если же кто-то процитирует "a waiting thread is selected" как свидетельство того, что выбирается всё же один из уже ждущих тредов, я спрошу иначе:
если есть несколько ждущих тредов и два треда одновременно вызывают SetEvent, есть ли гарантия, что разблокируются два ждущих треда, или такой гарантии всё же нет и один из SetEvent может потеряться?
no subject
Date: 2012-12-18 02:01 am (UTC)no subject
Date: 2012-12-18 02:20 am (UTC)(upd: а впрочем, конечно, эта гарантия не так критична в целом, как ситуация с потерей SetEvent)
Меж тем, несмотря на отсутствие подобных гарантий, всякие рассуждения о fairness синхронизаций имеют некоторое место в Computer Science.
А ведь попробуйте написать код, который достоверно детерминистически отличит strongly-fair semaphore от weakly-fair semaphore, или в классе weak semaphore различит busy-wait от, скажем, семафора, который "будит" произвольно один из ждущих тредов. ИМХО, это невозможно. Спрашивается - а зачем тогда вся эта наука? )))
no subject
Date: 2012-12-18 02:37 am (UTC)Он разблокирует ровно один поток при переходе signaled->not signaled.
Пока ждущих потоков нет, он будет висеть в состоянии signaled.
no subject
Date: 2012-12-18 02:43 am (UTC)а я пишу здесь о гарантиях fairness, которые, мне кажется, по своей природе сугубо статистические, и в некотором смысле "эзотерические". Т.е. ну вот лично я не знаю случая, чтоб кто-то написал busy-wait mutex и это приводило к реальным starvations (на тредах с одинаковым приоритетом, разумеется)
no subject
Date: 2012-12-18 02:54 am (UTC)Что касается busy-wait mutex'а, то потоки должны быть в процессе класса real-time. Иначе их приоритеты скачут случайным образом. И их должно быть много. В общем, это надо специально тестовый пример писать. И я подозреваю, что starvation таки можно устроить, если иметь исходные коды скедулера. Только кто ж нам их даст :D
no subject
Date: 2012-12-18 04:04 am (UTC)no subject
Date: 2012-12-18 02:50 am (UTC)no subject
Date: 2012-12-18 02:56 am (UTC)боюсь, я чуток смутно пишу на эту тему, это сугубо мои заморочки.
Я как раз наоборот пытаюсь понять, насколько те или иные гарантии могут иметь влияние на реальный работающий код. Т.е. вот так навскидку представить себе реальный, а не тщательно подобранный академический код, который будет ОЧЕНЬ ПЛОХО работать с busy-wait семафором, или вот вести себя сильно по-разному для тех или иных возможных опций реализации Event - я не смогу. Боюсь, я опять всё смутно излагаю...
no subject
Date: 2012-12-18 03:06 am (UTC)А такая реализация Event, с возможной потерей дополнительных сигналов и непредсказуемой очередностью, на мой взгляд, означает, что все потребители сигналов предполагаются эквивалентными (и вдобавок идемпотентными), и ситуация "сама садик я садила, сама буду поливать" приемлема.
no subject
Date: 2012-12-18 03:25 am (UTC)Скажем, иной сценарий - если у нас есть сервер, который обслуживает запросы, приходящие из трех тредов для троих пользователей -- вот тут возможна теоретически(!) ситуация, когда один из этих пользователей будет вытеснен двумя другими просто из-за non-fair synchronization. А вот для программы, которая не описывается как сервер нескольких независимых клиентов, подобрать даже теоретически, сценарий при котором что-то принципиально будет плохо работать - у меня не выходит. При том, что задача выглядит достаточно простой, в общем-то.
no subject
Date: 2012-12-18 03:38 am (UTC)no subject
Date: 2012-12-18 04:06 am (UTC)т.е. в "теории" знал давно, но в "теории" для начинающих можно вообще с умным видом сказать, что нужен FIFO fairness а остальное sucks.
no subject
Date: 2012-12-18 02:35 am (UTC)Подробнее: Auto-Reset Event, уходя в состояние not signaled, разблокирует ровно один ждущий поток. Это может быть и тот самый поток, который вызвал SetEvent(), если он вдруг потом сказал WaitForSingleObject().
no subject
Date: 2012-12-18 02:45 am (UTC)no subject
Date: 2012-12-18 02:52 am (UTC)