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)