【问题标题】:Is possible that a pthread_cond_wait() consumes multiple pthread_cond_signal()?pthread_cond_wait() 是否可能消耗多个 pthread_cond_signal()?
【发布时间】:2015-12-06 14:39:36
【问题描述】:

我在一些环境中测试过这个场景,得到了如下流程:

但是,从手册页 (http://linux.die.net/man/3/pthread_cond_wait) 或 (http://linux.die.net/man/3/pthread_cond_signal) 中,我无法保证以下情况不会发生:

在任何 等待 线程有机会运行之前,执行 信号 的 2 个线程可以运行。 (计划的可能性)

[现在,我知道如果这是使用信号量完成的,那么第二种情况将永远不会发生......但是在我的情况下,我真的需要使用 cond-vars 来做到这一点!]

在我的情况下,每个帖子都会增加谓词,所以当等待的 Thread2 唤醒时,它会检查谓词(在这种情况下增加 2),使线程不再休眠,它会减少谓词1(表示使用了一篇帖子)。

如果这种情况可能发生,这意味着“线程 1”可能不会唤醒,直到发生进一步的帖子,尽管谓词增加了两次(帖子)并且只减少了一次(线程 2 等待)。 更糟糕的是,第三次等待可能永远不会阻塞,因为它会消耗前一个挂起的谓词增量。

我还不能触发这个问题,但有谁知道这是否可能发生?


注意 为了克服这种可能性,我将pthread_cond_signal() 替换为pthread_cond_broadcast(),因此Thread1Thread2 都可以保证唤醒并消耗2 个增量。但是,这种解决方案会稍微降低(甚至可能不会显着)性能,而且我敢打赌,任何人都不会明白为什么我们在这里使用广播。

【问题讨论】:

    标签: c multithreading pthreads condition-variable


    【解决方案1】:

    不,一个pthread_cond_wait() 不可能消耗两个信号。

    pthread_cond_signal() 保证至少唤醒一个当前正在等待条件变量的线程。一旦一个线程发出信号,它就不再等待条件变量(尽管它可能仍在等待相关联的互斥体),因此后续的pthread_cond_signal() 必须唤醒一个不同等待线程(如果有)。

    (在您的第二张图中,第二个信号必须针对Thread2 以外的线程,因为此时Thread2 不再等待条件变量)。

    POSIX spec for pthread_cond_signal 中的确切措辞是:

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

    【讨论】:

    • 感谢您的回答。我假设一个线程被阻塞直到执行时刻(它试图获取互斥锁的时刻)。那么操作系统上是否有一种机制来“标记”线程? (意味着每个 pthread_cond_signal() 都会“取消标记”不同的线程?)
    • @Pacheco:这取决于操作系统的实现方式,但通常情况下阻塞在条件变量上的进程将处于等待队列中,并且向条件变量发出信号会自动将一个进程移出该队列。
    • @caf,先生,caf 和 POSIX 标准都说 pthread_cond_signal() 保证唤醒 至少一个 当前正在等待条件的线程变量。 那么,pthread_cond_signal() 可以让多个线程唤醒吗? 至少一个是什么意思?到目前为止,我一直认为该函数一次只能唤醒一个线程。我有些困惑。你介意解释一下吗?
    • @snr:是的,pthread_cond_signal() 被允许唤醒多个线程。 pthread_cond_signal() 是一种优化 - 任何正确的程序都可以将每次使用 pthread_cond_signal() 替换为 pthread_cond_broadcast() 并保持正确(尽管反过来不是为真)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-05-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-16
    • 2015-08-18
    相关资源
    最近更新 更多