【问题标题】:Can you signal a condition variable from a different mutex from the one that is waiting?您可以从与等待的互斥锁不同的互斥锁中发出条件变量的信号吗?
【发布时间】:2020-01-10 12:29:18
【问题描述】:

例如,在伪代码中:

lock mutex1
pthread_cond_wait(condition, mutex1)
unlock mutex1

...来自另一个线程:

lock mutex2
pthread_cond_signal(condition)
unlock mutex2

调用线程是否必须对正在等待的同一个互斥锁进行锁定?在我看来,这会限制条件变量的使用,当您有许多线程同时运行并希望相互通信时。

【问题讨论】:

  • 您认为这将如何限制它?是因为有额外的时间来锁定/解锁互斥锁吗? Linux 上的 Cv 实现通常会有一个内部互斥体,正是因为它必须支持通常在关键部分之外的信号。
  • @StaceyGirl 我是多线程的初学者,所以我真的不知道。

标签: c pthreads mutex condition-variable


【解决方案1】:

mutex2 与您的示例无关,您最好不要在通知程序中保留任何互斥锁。

文档说:

pthread_cond_signal() 可以被线程调用,无论它当前是否拥有调用 pthread_cond_wait() 的线程在等待期间与条件变量相关联的互斥锁;但是,如果需要可预测的调度行为,则该互斥锁应由调用 pthread_cond_broadcast() 或 pthread_cond_signal() 的线程锁定。

听起来您不需要任何特定的唤醒调度行为,所以是的,您可以在不持有任何互斥锁或持有不相关互斥锁的情况下向条件变量发出信号。

【讨论】:

  • 谢谢!究竟什么是“可预测的调度行为”?我不确定我是否需要。
  • 例如,如果您持有服务员的互斥锁,您可以阻止它继续执行,直到您释放该互斥锁并可能自己等待其他东西。大多数应用程序不需要可预测的调度。
  • 啊,有道理。非常感谢!
  • @SamuelNoyes:请注意(根本没有任何“可预测的调度行为”)这里不能保证一个线程不会在另一个线程开始等待信号之前发送信号;导致另一个线程等待一个信号,但为时已晚。这个问题的解决方案通常涉及使用某种变量或数据结构来告诉服务员它是否应该等待,这导致两个线程使用相同的互斥体来避免竞争条件(以防止“检查它是否应该等待,然后信号到达,然后开始等待信号”)。
  • @Brendan 您总是需要条件变量的共享谓词(与信号量不同),因为条件变量可能具有虚假唤醒。被唤醒的线程必须检查条件,如果条件不适合继续,则再次等待。信令线程通常必须持有互斥锁以修改谓词检查的某些状态(除非状态是原子的),否则非同步访问将是 UB。但是,信令线程发信号时不必持有互斥体,它可以在释放互斥体后发出信号,而无需UB或竞争。
猜你喜欢
  • 1970-01-01
  • 2015-07-12
  • 2010-12-07
  • 2011-02-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-05-07
相关资源
最近更新 更多