信号量的实现是如何工作的?
圣诞快乐!
我正在阅读信号量小书。书上有一个C语言的信号量实现,我不太明白。请参阅下面的代码。有这个唤醒变量。作者解释说:
wakeups 统计待处理信号的数量;即已被唤醒但尚未恢复执行的线程数量。唤醒的原因是为了确保我们的信号量具有属性 3,如第 4.3 节所述
和
性质3:当一个线程执行signal时,如果有线程在等待信号量,则必须唤醒其中一个等待线程。
好吧,我想我明白了属性的含义。等待线程之一应该获得互斥体,而不是另一个线程(例如信号线程)。如果我错了,请纠正我。我不明白的是这个机制是如何保证这个属性的。我想说的是,财产没有保障。非等待进程仍然有可能获得互斥锁。我缺少什么?
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);
}
Merry Xmas!
I'm reading the The Little Book of Semaphores. There is an implementation of semaphores in C in the book that I don't completely understand. See below for code. There is this wakeups variable. The author explains:
wakeups counts the number of pending signals; that is, the number of threads that have been woken but have not yet resumed execution. The reason for wakeups is to make sure that our semaphores have Property 3, described in Section 4.3
and
Property 3: if there are threads waiting on a semaphore when a thread executes signal, then one of the waiting threads has to be woken.
Ok, I think I understand the meaning of the property. One of the waiting threads should get the mutex and not another one (for example the signaling threads.) Correct me if I'm wrong. What I do not understand is how this property is guaranteed with this mechanism. I'd say the property is not guaranteed. It's still possible that a non-waiting process gets the mutex. What am I missing?
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);
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
wakeups
成员并不是为了保护互斥量不被等待线程以外的其他线程获取 - 它的目的是防止从sem_wait()
释放太多线程功能。cond_signal()
包装的pthread_cond_signal()
函数调用具有以下语句 在其文档中(添加了强调):和:
例如,当 3 个线程正在等待条件时,可能会在调用
cond_signal()
时释放两个(或全部三个)线程。wakeups
计数器确保只有适当数量的线程真正脱离sem_wait()
函数。其他的将保留在do
/while
循环中并再次等待条件。The
wakeups
member is not intended to protect the mutex from being acquired by something other than a waiting thread - it's intended to prevent too many threads from being released from thesem_wait()
function.The
pthread_cond_signal()
function call thatcond_signal()
wraps has the following statements in its documentation (emphasis added):And:
So as an example, it's possible that when 3 threads are waiting on the condition, that two (or all three) might be released when the
cond_signal()
call is made. Thewakeups
counter ensures that only the appropriate number of threads actually make it out of thesem_wait()
function. The other ones will remain in thedo
/while
loop and wait on the condition again.此属性的含义是,信号线程应代表等待线程之一(如果有)释放 CPU。
pthread_cond_signal() 正是出于同样的原因保证了这一点。
What this property means is that signaling thread should release CPU in behalf of one of waiting threads, if there are any.
pthread_cond_signal() guarantees exactly this and for the same reason.