gpt4 book ai didi

c - 被 pthread_cond_signal() 唤醒但失去对互斥锁竞争的线程会发生什么

转载 作者:行者123 更新时间:2023-12-04 12:31:46 27 4
gpt4 key购买 nike

关于这个: How To Use Condition Variable

假设我们有多个执行此类代码的消费者线程(从引用的页面复制):

while (TRUE) {
s = pthread_mutex_lock(&mtx);
while (avail == 0) { /* Wait for something to consume */
s = pthread_cond_wait(&cond, &mtx);
}
while (avail > 0) { /* Consume all available units */
avail--;
}
s = pthread_mutex_unlock(&mtx);
}

我假设这里的场景是:主线程调用 pthread_cond_signal() 来告诉消费者线程做一些工作。

据我了解 - 后续线程调用 pthread_mutex_lock() 然后调用 pthread_cond_wait() (它以原子方式解锁互斥锁)。到目前为止,没有一个消费者线程正在声明互斥锁,它们都在等待 pthread_cond_wait()。

当主线程调用pthread_cond_signal()时,跟随manpage ,至少一个线程被唤醒。当其中任何一个从 pthread_cond_wait() 返回时,它会自动声明互斥锁。

所以我的问题是:关于提供的示例代码现在会发生什么? 也就是说,输掉互斥锁的线程现在在做什么?

(AFAICT 赢得互斥锁的线程应该运行其余代码并释放互斥锁。丢失的线程应该等待互斥锁 - 在第一个 嵌套 while 循环 - 当获胜者持有它并在它被释放后开始阻塞 pthread_cond_wait() 因为到那时 while (avail == 0) 将被满足。我正确吗? )

最佳答案

请注意,pthread_cond_signal() 通常只用于唤醒一个等待线程(这是它所保证的全部)。但它可能会更“意外”地醒来。 while (avail > 0) 循环执行两个功能:

  • 它允许保证唤醒的一个线程消耗所有排队的工作单元
  • 它可以防止其他“意外”唤醒的线程假设有工作要做,而实际上可能没有工作要做,因为初始线程会处理所有这些工作。

它还可以防止在 while (avail > 0) 完成之后,但在工作线程再次等待条件之前,工作单元可能已被放置在队列中的竞争条件 -但是在调用 pthread_cond_wait() 之前,该比赛也由 if 测试处理。

基本上,当一个线程被唤醒时,它所知道的只是可能有工作单元供它使用,但可能没有(另一个线程可能已经使用它们)。

所以调用pthread_cond_signal()时发生的事件顺序是:

  • 系统将唤醒一个或多个等待条件的线程
  • 所有被唤醒的线程都将尝试获取互斥锁 - 只有其中一个线程可以在任何特定时刻获取它,因为这是互斥锁的目的
  • 该线程将继续执行,在 while (avail > 0) 循环中执行工作,然后将释放互斥锁
  • 此时,先前唤醒的其他线程之一将获取互斥锁并工作相同的循环,然后释放互斥锁。通常,将不再有可用的工作单元(因为第一个线程会消耗所有工作单元),但如果另一个线程添加了一个额外的单元(或更多),那么这个线程将处理该工作
  • 下一个线程将获取互斥体并执行同一组逻辑

关于c - 被 pthread_cond_signal() 唤醒但失去对互斥锁竞争的线程会发生什么,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6520826/

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