Jan*_*ard 3 c multithreading mutex semaphore conditional-statements
圣诞快乐!
我正在读"信号量小书".书中有一个C语言的实现,我并不完全理解.请参阅下面的代码.有这个唤醒变量.作者解释说:
唤醒计算未决信号的数量; 也就是说,已被唤醒但尚未恢复执行的线程数.唤醒的原因是为了确保我们的信号量具有第4.3节中描述的属性3
和
属性3:如果在线程执行信号时有线程在等待信号量,则必须唤醒其中一个等待线程.
好的,我想我理解了这个属性的含义.其中一个等待线程应该获取互斥锁而不是另一个(例如信令线程).如果我错了,请纠正我.我不明白的是这个机制如何保证这个属性.我说这家酒店不保证.非等待进程仍有可能获得互斥锁.我错过了什么?
typedef struct {
int value, wakeups;
Mutex *mutex;
Cond *cond;
} Semaphore;
// SEMAPHORE
Semaphore *make_semaphore (int value)
{
Semaphore *semaphore = check_malloc (sizeof(Semaphore));
semaphore->value = value;
semaphore->wakeups = 0;
semaphore->mutex = make_mutex ();
semaphore->cond = make_cond ();
return semaphore;
}
void sem_wait (Semaphore *semaphore)
{
mutex_lock (semaphore->mutex);
semaphore->value--;
if (semaphore->value < 0) {
do {
cond_wait (semaphore->cond, semaphore->mutex);
} while (semaphore->wakeups < 1);
semaphore->wakeups--;
}
mutex_unlock (semaphore->mutex);
}
void sem_signal (Semaphore *semaphore)
{
mutex_lock (semaphore->mutex);
semaphore->value++;
if (semaphore->value <= 0) {
semaphore->wakeups++;
cond_signal (semaphore->cond);
}
mutex_unlock (semaphore->mutex);
}
Run Code Online (Sandbox Code Playgroud)
该wakeups成员不是为了保护互斥锁不被等待线程以外的东西获取 - 它旨在防止从该sem_wait()函数中释放太多线程.
包装的pthread_cond_signal()函数调用在其文档中cond_signal()具有以下语句(强调添加):
该
pthread_cond_signal()函数应取消阻塞至少一个在指定条件变量cond上被阻塞的线程(如果有任何线程被阻塞cond).
和:
在多处理器上,实现可能无法
pthread_cond_signal()避免在条件变量上阻塞多个线程的阻塞.
举例来说,当3个线程在这个条件上等待时,可能会在cond_signal()调用时释放两个(或全部三个)线程.该wakeups计数器确保只有线程的适当数量居然能走出的sem_wait()功能.其他的将保留在do/ while循环中并再次等待条件.