pthread_cond_signal或pthread_cond_broadcast调用是否意味着写入内存屏障?

bdo*_*lan 4 c++ multithreading pthreads memory-barriers language-lawyer

通常使用条件变量,使得它们所引用的状态在互斥锁下被修改.但是,当状态只是一个仅设置标志时,不需要互斥锁来防止同时执行.所以有人可能想做这样的事情:

flag = 1;
pthread_cond_broadcast(&cvar);
Run Code Online (Sandbox Code Playgroud)

但是,如果pthread_cond_broadcast意味着写入内存屏障,这只是安全的; 否则,等待线程可能会在标志写入之前看到条件变量广播.也就是说,等待线程可能会唤醒,消耗cvar信号,但仍然看到标志0.

所以,我的问题是:pthread_cond_broadcastpthread_cond_signal调用是否意味着写内存障碍?如果是,那么在相关的POSIX(或其他)规范中指定了哪里?在这一点上,规范似乎不清楚.

注意:我知道,实际上,这确实会导致内存障碍(在Linux上,因为线程唤醒意味着完整的CPU内存障碍,而跨库函数调用意味着编译器内存障碍).但是,我对这些规范的保护感兴趣.

caf*_*caf 8

无论它是否意味着内存障碍,代码仍然不正确.考虑阅读方面:

while (flag == 0)
    pthread_cond_wait(&cvar, &mutex);
Run Code Online (Sandbox Code Playgroud)

如果读取端在测试flag == 0和执行等待之间暂停,则写入端可以执行flag = 1; pthread_cond_signal(&cvar);.读取方将完全错过唤醒 - 它将永远等待.请记住,唤醒不会排队 - 如果在发出条件变量信号时没有服务员,则信号无效.为避免这种情况,写端需要锁定互斥锁.

  • 从技术上讲,POSIX 确实承诺`pthread_cond_broadcast()` 是一个内存屏障(http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap04.html#tag_04_11)。但是,由于您的答案很好地详细说明,这对于所询问的目的没有用。 (2认同)