gpt4 book ai didi

c - 这个信号量的实现是如何工作的?

转载 作者:行者123 更新时间:2023-12-01 11:57:45 24 4
gpt4 key购买 nike

圣诞快乐!

我正在阅读 The Little Book of Semaphores .书中有一个用C语言实现的信号量,我不是很懂。请参阅下面的代码。有这个 wakeups 变量。作者解释:

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

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.

好的,我想我明白了属性的含义。等待线程之一应该获得互斥锁,而不是另一个线程(例如信号线程)。如果我错了,请纠正我。我不明白的是这种机制是如何保证这个属性的。我会说属性(property)没有保证。非等待进程仍然有可能获得互斥量。我错过了什么?

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);
}

最佳答案

wakeups 成员不是为了保护互斥锁不被等待线程以外的东西获取 - 它是为了防止太多线程从 sem_wait() 函数。

cond_signal() 包装的pthread_cond_signal() 函数调用具有以下语句 in its documentation (强调):

The pthread_cond_signal() function shall unblock at least one of the threads that are blocked on the specified condition variable cond (if any threads are blocked on cond).

和:

On a multi-processor, it may be impossible for an implementation of pthread_cond_signal() to avoid the unblocking of more than one thread blocked on a condition variable.

举个例子,当有 3 个线程在等待条件时,这两个(或所有三个)可能会在调用 cond_signal() 时被释放。 wakeups 计数器可确保只有适当数量的线程才能真正脱离 sem_wait() 函数。其他的将保留在 do/while 循环中并再次等待条件。

关于c - 这个信号量的实现是如何工作的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4526182/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com