Re: Порядок захвата mutex'ов.
- From
- Valentin Nechayev ()
- To
- "mitrohin a.s." ()
- Date
- 2003-05-29T17:33:06Z
- Area
- RU.UNIX.PROG
From: Valentin Nechayev <netch@segfault.kiev.ua>
>>> mitrohin a.s. wrote:
>>> imho имелось ввиду что поток проснется, но застрянет внутри cond_wait() на
>>> захвате mutex.
AP>> А я его не захватывал ваще. Смотри:
AP>> тред1: лок, вэйт, анлок
AP>> тред2: сигнал
AP>> синхронизация была сделана другими сигналами/мутексами. Т.е. есть пул
AP>> тредов, им даются задания, если все треды заняты и задания давать некому,
AP>> то выполнялась последовательность "тред1", когда кто-то освобождался, он
AP>> давал сигнал. Так вот, "тред1" просто не просыпался.
mas> вот и вы на ступили на те же грабли что и я ;)))
mas> нельзя пользоваться cond без вспомогательной переменной
Как именно нельзя пользоваться? wait - да, нельзя.
signal - можно (осторожно).
mas> thread 1 thread 2
mas> -------------------------------------------------------------------
mas> cond_broadcast()
mas> cond_wait()
mas> broadcast пришел до того как первый поток сел на cond_wait()
mas> и естественно этот broadcast не получил ;))
Ну и что с того, что он его не получил?
Данные изменены, mutex освобождён. Первый проверяет данные и или по результатам
проверки не уходит в спячку, или уходит, тогда ему, наоборот, не надо получать
сигнал, потому что ничего в данных не изменилось.
Наоборот, если cond_signal() был сделан после mutex_unlock(), а первый тред
уснел уснуть на cond_wait(), то будет spurious wakeup (случайное, беспричинное
пробуждение).
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> или нет...
Не фиолетово. cond_{signal|broadcast} без лока даст шанс spirious wakeup.
Это не должно быть фатальным (в SUSv3 в мане по pthread_cond_[timed]wait()
явно сказано, что spirious wakeups разрешены по любым причинам), но без
причины вызывать его тоже не стоит.
-netch-
--- ifmail v.2.15dev5
* Origin: Dark side of coredump (2:5020/400)