调用 pthread_cond_signal 而不锁定互斥锁

发布于 2024-10-09 06:23:34 字数 336 浏览 8 评论 0 原文

我在某处读到,我们应该在调用 pthread_cond_signal 之前锁定互斥体,并在调用后解锁互斥体:

pthread_cond_signal() 例程是 用于向另一个人发出信号(或唤醒) 正在等待的线程 条件变量。应该是 互斥体锁定后调用,并且必须 解锁互斥体以便 pthread_cond_wait() 例程 完成。

我的问题是:在不锁定互斥体的情况下调用 pthread_cond_signalpthread_cond_broadcast 方法不是可以吗?

I read somewhere that we should lock the mutex before calling pthread_cond_signal and unlock the mutex after calling it:

The pthread_cond_signal() routine is
used to signal (or wake up) another
thread which is waiting on the
condition variable. It should be
called after mutex is locked, and must
unlock mutex in order for
pthread_cond_wait() routine to
complete.

My question is: isn't it OK to call pthread_cond_signal or pthread_cond_broadcast methods without locking the mutex?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

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

发布评论

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

评论(3

九厘米的零° 2024-10-16 06:23:34

如果您不锁定更改条件和信号的代码路径中的互斥锁,则可能会丢失唤醒。考虑这对进程:

进程 A:

pthread_mutex_lock(&mutex);
while (condition == FALSE)
    pthread_cond_wait(&cond, &mutex);
pthread_mutex_unlock(&mutex);

进程 B(不正确):

condition = TRUE;
pthread_cond_signal(&cond);

然后考虑这种可能的指令交错,其中 condition 开始为 < code>FALSE:

Process A                             Process B

pthread_mutex_lock(&mutex);
while (condition == FALSE)

                                      condition = TRUE;
                                      pthread_cond_signal(&cond);

pthread_cond_wait(&cond, &mutex);

条件现在为TRUE,但进程 A 一直在等待条件变量 - 它错过了唤醒信号。如果我们改变进程 B 来锁定互斥体:

进程 B(正确):

pthread_mutex_lock(&mutex);
condition = TRUE;
pthread_cond_signal(&cond);
pthread_mutex_unlock(&mutex);

...那么上述情况就不会发生;唤醒永远不会错过。

(请注意,实际上您可以pthread_cond_signal()本身移到pthread_mutex_unlock()之后,但这可能会导致线程调度效果不佳,并且由于条件本身的更改,您必须锁定此代码路径中已经存在的互斥体)。

If you do not lock the mutex in the codepath that changes the condition and signals, you can lose wakeups. Consider this pair of processes:

Process A:

pthread_mutex_lock(&mutex);
while (condition == FALSE)
    pthread_cond_wait(&cond, &mutex);
pthread_mutex_unlock(&mutex);

Process B (incorrect):

condition = TRUE;
pthread_cond_signal(&cond);

Then consider this possible interleaving of instructions, where condition starts out as FALSE:

Process A                             Process B

pthread_mutex_lock(&mutex);
while (condition == FALSE)

                                      condition = TRUE;
                                      pthread_cond_signal(&cond);

pthread_cond_wait(&cond, &mutex);

The condition is now TRUE, but Process A is stuck waiting on the condition variable - it missed the wakeup signal. If we alter Process B to lock the mutex:

Process B (correct):

pthread_mutex_lock(&mutex);
condition = TRUE;
pthread_cond_signal(&cond);
pthread_mutex_unlock(&mutex);

...then the above cannot occur; the wakeup will never be missed.

(Note that you can actually move the pthread_cond_signal() itself after the pthread_mutex_unlock(), but this can result in less optimal scheduling of threads, and you've necessarily locked the mutex already in this code path due to changing the condition itself).

夜光 2024-10-16 06:23:34

根据本手册:

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

Dave Butenhof(使用 POSIX 线程进行编程)位于 comp.programming.threads 上,并且可以使用 此处

According to this manual :

The pthread_cond_broadcast() or
pthread_cond_signal() functions
may be called by a thread whether or not it currently owns the mutex that
threads calling pthread_cond_wait()
or pthread_cond_timedwait() have
associated with the condition variable
during their waits; however, if
predictable scheduling behavior is
required, then that mutex shall be
locked by the thread calling
pthread_cond_broadcast() or
pthread_cond_signal().

The meaning of the predictable scheduling behavior statement was explained by Dave Butenhof (author of Programming with POSIX Threads) on comp.programming.threads and is available here.

回眸一遍 2024-10-16 06:23:34

caf,在您的示例代码中,进程 B 修改 condition 而不首先锁定互斥体。如果进程 B 在修改期间只是锁定互斥体,然后在调用 pthread_cond_signal 之前仍然解锁互斥体,那么就不会有问题 --- 我的说法正确吗?

我凭直觉相信 caf 的位置是正确的:在不拥有互斥锁的情况下调用 pthread_cond_signal 是一个坏主意。但咖啡馆的例子实际上并不是支持这一立场的证据;这只是支持更弱(实际上不言而喻)的立场的证据,即除非您首先锁定了该互斥体,否则修改由互斥体保护的共享状态是一个坏主意。

任何人都可以提供一些示例代码,其中调用 pthread_cond_signal 后跟 pthread_mutex_unlock 会产生正确的行为,但调用 pthread_mutex_unlock 后跟 pthread_cond_signal > 产生不正确的行为?

caf, in your sample code, Process B modifies condition without locking the mutex first. If Process B simply locked the mutex during that modification, and then still unlocked the mutex before calling pthread_cond_signal, there would be no problem --- am I right about that?

I believe intuitively that caf's position is correct: calling pthread_cond_signal without owning the mutex lock is a Bad Idea. But caf's example is not actually evidence in support of this position; it's simply evidence in support of the much weaker (practically self-evident) position that it is a Bad Idea to modify shared state protected by a mutex unless you have locked that mutex first.

Can anyone provide some sample code in which calling pthread_cond_signal followed by pthread_mutex_unlock yields correct behavior, but calling pthread_mutex_unlock followed by pthread_cond_signal yields incorrect behavior?

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