【问题标题】:Can pthread_cond_wait() always win the competition in locking a mutex?pthread_cond_wait() 能否在锁定互斥锁的竞争中始终获胜?
【发布时间】:2016-11-13 06:10:19
【问题描述】:

这个问题是关于llnl 中的 pthread 教程。 假设有三个线程。

线程 1:

pthread_mutex_lock(&mutex)
do_something...
if condition
    pthread_cond_signal(&con)
pthread_mutex_unlock(&mutex)
repeat

线程 2:

pthread_mutex_lock(&mutex)
do_something...
if condition
    pthread_cond_signal(&con)
pthread_mutex_unlock(&mutex)
repeat

线程 3:

pthread_mutex_lock(&mutex)
while(condition not holds)
    pthread_cond_wait(&con)
    do_something...
pthread_mutex_unlock(&mutex)

假设 Thread1 检查条件是否满足,然后发送信号唤醒 Thread3。最后它解锁了互斥锁。但与此同时,线程 2 正在尝试锁定互斥体。

我的问题是:是否可以保证 Thread3 将永远在比赛中获胜?

如果不是,那么在 Thread2 do_something... 之后,条件变量可能会改变,那么当 Thread3 锁定互斥体时,条件变量与什么不同它期望。

【问题讨论】:

  • 没有这样的保证。如果它发生了 10 次中的 10 次,那还是完全不走运。
  • 没有这样的保证。这正是为什么您需要围绕pthread_cond_wait 的while 循环!出于同样的原因,您不应该在该 while 循环中包含 do_something...

标签: c++ c multithreading pthreads


【解决方案1】:

我的问题是:是否可以保证 Tread3 永远在比赛中获胜?

没有这样的保证。来自POSIX

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

如果在一个条件变量上阻塞了多个线程,则 调度策略应确定线程的顺序 unblocked. 当每个线程由于一个 pthread_cond_broadcast() 或 pthread_cond_signal() 从其返回 调用 pthread_cond_wait() 或 pthread_cond_timedwait(),线程 应拥有调用 pthread_cond_wait() 的互斥锁或 pthread_cond_timedwait()。 未阻塞的线程应 根据调度策略竞争互斥锁(如果 适用),并且好像每个都调用了 pthread_mutex_lock()。

(强调我的)。

如果不是,那么在 Tread2 do_something... 之后,条件变量可能会发生变化,那么当 Tread3 锁定互斥体时,条件变量会与预期不同。

如果线程的执行顺序很重要,那么您可能需要重写代码。

【讨论】:

    【解决方案2】:

    没有保证。从pthread_cond_wait() 返回应该被视为暗示条件可能已经改变,而不是它肯定已经改变 - 所以你需要重新检查条件,并且可能需要再次等待。这正是为什么应该在检查条件的循环中调用 pthread_cond_wait()

    【讨论】:

      猜你喜欢
      • 2014-11-08
      • 2010-11-22
      • 1970-01-01
      • 2013-02-02
      • 2012-10-27
      • 1970-01-01
      • 2011-09-12
      • 1970-01-01
      相关资源
      最近更新 更多