thread - синхронизация потоков c#




Внутренняя реализация Lock(Monitor) в.NET. (2)

Для освоения некоторых технологий вы должны знать, как это делается на одном уровне абстракции ниже. В случае многопоточного программирования полезно знать о примитивах синхронизации.
Вот вопрос, как реализован Lock (Monitor) в .NET?

Меня интересуют такие моменты:
- использует ли он OS-объекты ?;
- требуется ли режим пользователя или режим ядра ?;
- что накладные расходы для потоков, которые ждут блокировки ?;
- в каких случаях может быть нарушена очередь на очереди, ожидающая блокировки ?.

Обновлено:
«Если более чем один поток поддерживает блокировку, они ставятся в очередь на« готовую очередь »и предоставляют блокировку на основе« первым пришел, первым обслужен ». Примечание: Нюансы в поведении Windows и CLR означают, что справедливость очередь иногда может быть нарушена ». [C # 4.0 в двух словах, Джозеф Альбахари] Так вот об этом я и спрашиваю в последнем вопросе, касающемся« нарушенной очереди ».


В статье в Википедии есть довольно хорошее описание того, что такое «Монитор», а также его базовая технология - «Переменная состояния».

Обратите внимание, что .NET Monitor - это правильная реализация переменной условия; большинство опубликованных версий резюме Win32 неверны, даже те, которые содержатся в обычно уважаемых источниках, таких как доктор Доббс. Это связано с тем, что CV нельзя легко создать из существующих примитивов синхронизации Win32 .

Вместо создания неглубокой (и некорректной) оболочки поверх примитивов Win32 реализация .NET CV использует тот факт, что она находится на платформе .NET, реализуя собственные очереди ожидания и т. Д.


После некоторых исследований я узнал ответы на свои вопросы. В целом CodeInChaos и Хенк Холтерман были правы, но вот некоторые подробности.

Когда поток начинает бороться за блокировку с другими потоками, сначала он затягивает цикл ожидания, пытаясь получить блокировку. Все эти действия выполняются в пользовательском режиме . Тогда, если не удастся создать объект OS ядра ОС, поток переключается в режим ядра и ждет сигнала от этого Event .

Поэтому ответьте на мои вопросы:
1. В лучшем случае нет, но в худшем да (объект Event лениво создает, если требуется);
2. В общем случае он работает в пользовательском режиме, но если потоки слишком долго конкурируют за блокировку, поток можно переключить в режим ядра (через вызов неуправляемой функции Win API);
3. Накладные расходы для переключения из режима пользователя в режим ядра (~ 1000 циклов процессора);
4. Microsoft заявляет, что это «честный» алгоритм, такой как FIFO, но это не гарантирует этого. (Например, если поток из очереди ожидания будет приостановлен, он перемещается в конец очереди, когда он будет возобновлен.)







monitor