- 论坛徽章:
- 3
|
回复 23# windoze
果然够专业, 论文都搬出来了, 下面是论文里面描述的信号丢失的情况,看到没后面有个解决方案:
解决方案就是在睡眠之前再检查一次有没有naked notify 产生,
- RACE problem, and notify can be lost. How?
+ since NOTIFY is just a hint
+ a process in the monitor, find <OK to proceed> to be FALSE, about to WAIT
(of course, in this case, process is holding monitor lock)
+ now, device does a naked NOTIFY, it does not need to acquire lock
+ The WAIT then be done, and the NOTIFY is lost
- Note: this never happens if device requires to hold lock before doing NOTIFY
- Solution:
+ add a binary state to conditional variable.
+ whenever there is a naked notify, that bit is turned on
+ WAIT then check for that state before do a really wait
+ update to this state need to be atomic
+ this is similar to binary-semaphor
下面是linux的实现, 从”man pthread_cond_signal“ 搬出来的
pthread_cond_wait(mutex, cond):
value = cond->value; /* 1 */
pthread_mutex_unlock(mutex); /* 2 */
pthread_mutex_lock(cond->mutex); /* 10 */
if (value == cond->value) { /* 11 */
me->next_cond = cond->waiter;
cond->waiter = me;
pthread_mutex_unlock(cond->mutex);
unable_to_run(me);
} else
pthread_mutex_unlock(cond->mutex); /* 12 */
pthread_mutex_lock(mutex); /* 13 */
pthread_cond_signal(cond):
pthread_mutex_lock(cond->mutex); /* 3 */
cond->value++; /* 4 */
if (cond->waiter) { /* 5 */
sleeper = cond->waiter; /* 6 */
cond->waiter = sleeper->next_cond; /* 7 */
able_to_run(sleeper); /* 8 */
}
pthread_mutex_unlock(cond->mutex); /* 9 */
看起来linux的实现跟论文solution描述的产不多,真正的睡眠之前会检查下有没有signal产生, 也就是判断value == cond->value
如果有signal产生value == cond->value是false, linux不管signal 是不是naked, 在signal的时候会递增cond->value
这是安全的, 因为cond还有个内部锁cond->mutex保护
在cond->mutex保护下, 不管是pthread_cond_wait先跑还是pthread_cond_signal都没关系, 不会产生信号丢失。 |
|