信号量的实现是如何工作的?

发布于 2024-10-09 09:44:31 字数 1429 浏览 0 评论 0原文

圣诞快乐!

我正在阅读信号量小书。书上有一个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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

九公里浅绿 2024-10-16 09:44:31

wakeups 成员并不是为了保护互斥量不被等待线程以外的其他线程获取 - 它的目的是防止从 sem_wait() 释放太多线程功能。

cond_signal() 包装的 pthread_cond_signal() 函数调用具有以下语句 在其文档中(添加了强调):

pthread_cond_signal() 函数应取消阻止至少一个在指定条件变量 cond 上被阻止的线程(如果有任何线程)在 cond 上被阻止)。

和:

在多处理器上,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 the sem_wait() function.

The pthread_cond_signal() function call that cond_signal() wraps has the following statements in its documentation (emphasis added):

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).

And:

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.

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. The wakeups counter ensures that only the appropriate number of threads actually make it out of the sem_wait() function. The other ones will remain in the do/while loop and wait on the condition again.

昵称有卵用 2024-10-16 09:44:31

此属性的含义是,信号线程应代表等待线程之一(如果有)释放 CPU。
pthread_cond_signal() 正是出于同样的原因保证了这一点。

pthread_cond_signal() 函数应至少解除对指定条件变量 cond 上阻塞的一个线程的阻塞(如果有任何线程在 cond 上阻塞)。

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.

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).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文