Здравствуйте, okman, Вы писали:
O>Спинлок в такой имплементации — это вообще, как по мне, плохая идея.
Если этим спинлоком защищать только условные Get/Set для некоторого (общего для потоков) значения, то идея вроде как хорошая.
Но, конечно же, при использовании его есть риск завесить приложение, если вынесли в него некие сложные действия.
O>Во-первых, постоянно теребить глобальную переменную с xchg/cmpxchg и блокировкой шины — не есть гуд
O>(bus traffic и все такое). Как минимум, тут надо применять стратегию не "test and set", а
O>"test test and set" + какую-то разгрузку в виде yield/pause/Sleep/etc.
+100500
Вот именно о разгрузке в виде ::Sleep — я и сообщал здесь выше!
![](/Forum/Images/smile.gif)
В виде
Sleep или
WaitingFor... ввести ожидание, чтобы передать управление диспетчеру потоков.
O>Во-вторых, на однопроцессорной машине крутиться в спин-цикле бессмысленно, так как лок никто в
O>это время не освободит.
Да, однопроцессорных сейчас уже давно нет, но когда-то (лет 15 назад) как-то же работала многопоточка?
O>Ну и в-третьих, если между захватом и освобождением лока поток будет вытеснен, получится
O>очень некрасивая ситуация по отношению к другим потокам, которые ждут его освобождения.
Вероятность того, что поток будет вытеснен, если внутри этого лока — только один вызов гетера/сетера — фактически нулевая.
O>Особенно если лок не гарантирует порядок захвата. Так легко и систему завесить, особенно если
O>такой спинлок применять где-нибудь в критических местах — драйверы, всякие системные
O>обработчики и т.д. Встречал на практике.
+100500
Да, если внутрь этого лока вносить что-то длинное, то такое бывает. Я когда-то также сталкивался с этим.
Но здесь — вся ответственность на разработчике
![](/Forum/Images/frown.gif)
Каких-либо механизмов, способных разрулить проблему IMHO не существует.
Кроме, разве что сделать ожидание в локе — с прокачкой сообщений ОС, и с вызовом Sleep...