2013-02-26 2 views
11

Когда мьютекс уже заблокирован T1, а T2 пытается его заблокировать, каков процесс для T2?Реализация и сигнализация Mutex

Я думаю, что идет что-то вроде этого:

-T2 пытается заблокировать, терпит неудачу, может быть Взаимные блокировки немного, а затем вызывает выход ...
-T2 запланирован на выполнение пару раз, пытается зафиксировать не удается, дает ...
-Eventually T1 отпирает, T2 планируется к исполнению и удается заблокировать мьютекс ...

ли T1 разблокировки на явно сигнализировать планировщик или другие потоки, которые мьютекс разблокирован? Или он просто разблокируется и оставляет планировщик планировать заблокированные потоки, когда он считает это подходящим для этого (у какого-либо планировщика нет понятия заблокированных потоков и он не рассматривает их как специальные)?

+1

'Я думаю, что принцип взаимного исключения гарантирует, что в критический раздел одновременно войдут 2 или более потока. Теперь, есть ли у вас очередь для потоков, которые пытаются заблокировать мьютекс, или вы просто делаете ожидание до тех пор, пока мьютекс не будет свободен, зависит от того, как вы его реализуете и каковы ваши потребности в мьютексе. Например, «mutex» в RTOS, например VxWorks, реализует приоритетный потоковый протокол, который вам может не понадобиться в ОС общего назначения (GPOS). – Raj

ответ

3

Короче: да, возможно ...

Это детали реализации, и это довольно трудно сказать, не по крайней мере понимающей какую операционную систему вы говорите. Как правило, разблокировка мьютекса будет отмечать только ожидаемый поток как «runnable», но не (обязательно) вызывает планировщик в это время - и даже если планировщик вызывается, это не означает, что T2 будет следующим потоком бежать.

В Linux код вводится в mutex_unlock(), который проверяет, есть ли какая-либо ожидающая задача (проверяя, является ли количество блокировок меньше нуля - оно начинается с 1 для разблокировки, один запрос блокировки возвращает его нулю, дальнейшая попытка блокировки сделает его отрицательным). Если есть еще один процесс ожидания, он вызывает «медленную разблокировку пути», которая через пару функций перенаправления, чтобы разрешить детали реализации, заканчивается в __mutex_unlock_common_slowpath - несколько строк дальше вниз, есть вызов wake_up_process, который в конечном итоге заканчивается в try_to_wake_up - который по сути просто ставит задачу в очередь как «готовую к запуску», а затем вызывает планировщик (через несколько уровней функций!)

+0

, так что вы говорите, что в потоке linux эти блоки отмечены как not runnable (так что график не будет планировать его до того, как он будет помечен как runable) – NoSenseEtAl

+0

Да, это правильно. Предполагается, что вы используете ядро ​​mutex tho ', которое может быть не таким, как, например, pthread_mutex. –

+0

очень хороший ответ ... кстати, без меня вас много беспокоит ... можете ли вы быстро сказать, отличается ли futex от этого каким-то значительным образом. – NoSenseEtAl

6

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

Спиннинг и спиннинг с yield имеют ужасное представление. Теоретически контролируемое пользователем планирование (см. Scheduler activations) должно иметь наилучшую производительность, но насколько я знаю, никто никогда не делал его работоспособным во всех случаях. Переменные условия общего назначения в ядре и специальные блокирующие примитивы с поддержкой ядра должны работать более или менее одинаково с futex в Linux как лучший пример последнего.

Бывают ситуации, когда спиннинг может иметь лучшую производительность. В Solaris некоторый фиксирующий примитив в ядре имеет адаптивный режим, в котором блокировка вращается до тех пор, пока процесс, удерживающий блокировку, работает на другом процессоре. Если владелец замка спит или получает превенцию, официант замка тоже ложится спать. В других ядрах есть классы блокировок, в которых владелец замка не может быть выгружен или спящий, удерживая замок, поэтому в этих случаях вращение тоже хорошо работает. В общем, хотя, в частности, в userland, вращение имеет такие ужасные дегенеративные случаи (процесс прядения вращается, пока он не освобождается, чтобы позволить владельцу замка работать), что это очень плохо для производительности. Обратите внимание, что специализированные блокирующие примитивы, такие как futex, могут реализовывать такие оптимизации, что обычно не могут использоваться для переменных общего назначения.

+0

приятный A, но «Пряди и спиннинг с урожайностью имеют ужасную производительность» должны быть квалифицированы ... Я могу представить сценарии низкого соперничества и небольшого количества работы под замком, где быстрые шпиндельные блоки. – NoSenseEtAl

+1

ВСЕ замки (вполне) эффективны, когда нет споров. Хорошо разработанные методы блокировки ТАКЖЕ эффективны, когда есть высокая конкуренция. Это также зависит от количества доступных процессоров. Ожидание «вращения» ужасно для одной процессорной системы, потому что другой поток, который в данный момент удерживает блокировку, не будет запущен, а T2 использует весь процессор для проверки того, будет ли T1 который не успевает запустить, выпустил блокировку - это довольно бесполезное использование CPU-времени. –

+0

@Mats Я думал о многоядерной системе, но я согласен с вами в отношении одного ядра. – NoSenseEtAl

1

Скажут мы следующий сценарий:

1. T1 got M1. M1 locked. 
2. T2 tries to get M1 and gets blocked as M1 is locked. 
3. T3 tries to get M1 and gets blocked as M1 is locked. 
4. ...some time later... 
5. T1 unlocks M1.* 
6. T2 got M1. 
7. T3 is unblocked and tries to get M1 but is blocked again as T2 got M1 first. 

* Системный вызов, разблокировки, должен сообщает всем заблокированы задачи/процессы/темы, которые блокируются на блокировке вызова мьютекса в , Затем они запланировано на выполнение. Это не означает, что они выполняются, поскольку в ходе выполнения может быть уже кто-то. Как утверждают другие, это зависит от реализации, как это делается. Если вы действительно хотите это хорошо изучить, я бы рекомендовал это book

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