Re: Порядок захвата mutex'ов.

From
mitrohin a.s. ()
To
Valentin Nechayev ()
Date
2003-05-30T12:21:28Z
Area
RU.UNIX.PROG
From: "mitrohin a.s." <swp@uni-altai.ru>

Valentin Nechayev <netch@segfault.kiev.ua> wrote:
>>>> mitrohin a.s. wrote: 

>>>> imho имелось ввиду что поток проснется, но застрянет внутри cond_wait() на
>>>> захвате mutex.
 AP>>> А я его не захватывал ваще. Смотри:
 AP>>> тред1: лок, вэйт, анлок
 AP>>> тред2: сигнал
 AP>>> синхронизация была сделана другими сигналами/мутексами. Т.е. есть пул
 AP>>> тредов, им даются задания, если все треды заняты и задания давать некому,
 AP>>> то выполнялась последовательность "тред1", когда кто-то освобождался, он
 AP>>> давал сигнал. Так вот, "тред1" просто не просыпался.
mas>> вот и вы на ступили на те же грабли что и я ;)))
mas>> нельзя пользоваться cond без вспомогательной переменной

 VN> Как именно нельзя пользоваться? wait - да, нельзя.
я про wait

 VN> signal - можно (осторожно).

mas>>    thread 1                        thread 2
mas>> -------------------------------------------------------------------
mas>>                                    cond_broadcast()
mas>>    cond_wait()
mas>> broadcast пришел до того как первый поток сел на cond_wait()
mas>> и естественно этот broadcast не получил ;))

 VN> Ну и что с того, что он его не получил?
 VN> Данные изменены, mutex освобождён. Первый проверяет данные и или по результатам
 VN> проверки не уходит в спячку, или уходит, тогда ему, наоборот, не надо получать
 VN> сигнал, потому что ничего в данных не изменилось.
 VN> Наоборот, если cond_signal() был сделан после mutex_unlock(), а первый тред
 VN> уснел уснуть на cond_wait(), то будет spurious wakeup (случайное, беспричинное
 VN> пробуждение).
полностью согласен... я имел ввиду что cond используется сам по себе как 
таковой - и нет данных которые проверяются - просто mutex_lock, cond_wait и 
cond_signal

mas>>    mutex_lock(mtx);                |       mutex_lock(mtx);
mas>>    signalled = 1;                  |       signalled = 1;
mas>>    cond_broadcast(cond);           |       
mas>>    mutex_unlock(mtx);              |       mutex_unlock(mtx)
mas>>                                    |       cond_broadcast(cond);
mas>>    ...
mas>> }
mas>> и для thread2() фиолетово где cond_broadcast(), внутри блока lock-unlock
mas>> или нет...

 VN> Не фиолетово. cond_{signal|broadcast} без лока даст шанс spirious wakeup.
 VN> Это не должно быть фатальным (в SUSv3 в мане по pthread_cond_[timed]wait()
 VN> явно сказано, что spirious wakeups разрешены по любым причинам), но без
 VN> причины  вызывать его тоже не стоит.
просто у меня фиолетовый цвет наверное не такой яркий ;)) поэтому принимая во
внимание все выше сказанное - фиолетово.

/swp
--- ifmail v.2.15dev5
 * Origin: BSPU InterNetNews site (2:5020/400)