我正在尝试了解条件变量以及如何在生产者 - 消费者情况下使用它.我有一个队列,其中一个线程将数字推入队列,而另一个线程从队列中弹出数字.我希望在生产线程放置一些数据时使用条件变量来指示消费线程.问题是有时(或大多数时候)它只将两个项目推入队列然后挂起.我在produce()函数中指出它在调试模式下运行时停止.任何人都可以帮我指出为什么会这样吗?
我有以下全局变量:
boost::mutex mutexQ; // mutex protecting the queue
boost::mutex mutexCond; // mutex for the condition variable
boost::condition_variable condQ;
Run Code Online (Sandbox Code Playgroud)
以下是我的消费者主题:
void consume()
{
while( !bStop ) // globally declared, stops when ESC key is pressed
{
boost::unique_lock lock( mutexCond );
while( !bDataReady )
{
condQ.wait( lock );
}
// Process data
if( !messageQ.empty() )
{
boost::mutex::scoped_lock lock( mutexQ );
string s = messageQ.front();
messageQ.pop();
}
}
}
Run Code Online (Sandbox Code Playgroud)
下面是我的制作人主题:
void produce()
{
int i = 0;
while(( !bStop ) …Run Code Online (Sandbox Code Playgroud) 由于不必要的性能影响,我的问题特别提到为什么它是这样设计的.
当线程T1有这个代码时:
cv.acquire()
cv.wait()
cv.release()
Run Code Online (Sandbox Code Playgroud)
和线程T2有这个代码:
cv.acquire()
cv.notify() # requires that lock be held
cv.release()
Run Code Online (Sandbox Code Playgroud)
会发生什么是T1等待并释放锁定,然后T2获取它,通知cv哪个唤醒T1.现在,在T2的释放和T1的重新获得之后存在一个竞争条件wait().如果T1尝试首先重新获取,则在T2 release()完成之前将不必要地重新暂停.
注意:我故意不使用该with语句,以更好地说明显式调用的竞争.
这似乎是一个设计缺陷.有没有任何已知的理由,或者我错过了什么?
python multithreading condition-variable race-condition python-3.x
wait_for "阻塞当前线程,直到条件变量被唤醒或在指定的超时持续时间之后"
wait_until "阻止当前线程,直到条件变量被唤醒或达到指定的时间点"
有什么不同?是否会wait_until旋转,以便线程可以在发出信号时完全(或多或少)继续,而wait_for只是将线程添加回调度点?
它是在POSIX线程教程https://computing.llnl.gov/tutorials/pthreads/ 中编写的 ,这是一个逻辑错误.
我的问题是为什么它是一个逻辑错误?
在我的程序中,我需要使用这些信号,但是我不能保证会有一个处于_cond_wait状态的线程.我试图测试它,没有任何反应.这会导致意外行为还是更糟?
谢谢!
我可能失去了一些东西很明显,但我看不到之间有什么区别std::condition_variable和std::condition_variable_any.为什么我们两个都需要?
我需要一些帮助来了解如何在C中使用条件变量来解决练习.这是一个小例子:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
#include <string.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <fcntl.h>
#define OKTOWRITE "/oktowrite"
#define MESSAGE "/message"
#define MUTEX "/lock"
int main(int argc, char** argv)
{
pthread_cond_t* condition;
pthread_mutex_t *mutex;
char* message;
int des_cond, des_msg, des_mutex;
int mode = S_IRWXU | S_IRWXG;
des_mutex = shm_open(MUTEX, O_CREAT | O_RDWR | O_TRUNC, mode);
if (des_mutex < 0)
{
perror("failure on shm_open on des_mutex");
exit(1);
}
if (ftruncate(des_mutex, sizeof(pthread_mutex_t)) == -1)
{
perror("Error …Run Code Online (Sandbox Code Playgroud) 我正在尝试了解条件变量.我想知道使用条件变量的常见情况.
一个示例是在阻塞队列中,其中两个线程访问队列 - 生产者线程将项目推入队列,而使用者线程从队列中弹出一个项目.如果队列为空,则消费者线程正在等待,直到生产者线程发送信号.
您需要使用条件变量的其他设计情况是什么?
我更喜欢基于经验的例子,例如真实应用程序中的例子.
以下是使用条件变量的典型方法:
// The reader(s)
lock(some_mutex);
if(protected_by_mutex_var != desired_value)
some_condition.wait(some_mutex);
unlock(some_mutex);
// The writer
lock(some_mutex);
protected_by_mutex_var = desired_value;
unlock(some_mutex);
some_condition.notify_all();
Run Code Online (Sandbox Code Playgroud)
但是,如果通过比较和交换指令原子地设置protected_by_mutex_var,则互斥量是否可用于任何目的(除了pthread和其他API要求您传入互斥锁)?是否保护用于实施条件的状态?如果没有,那么这样做是否安全?:
// The writer
atomic_set(protected_by_mutex_var, desired_value);
some_condition.notify_all();
Run Code Online (Sandbox Code Playgroud)
作者永远不会直接与读者的互斥体互动?请注意,'protected_by_mutex_var'名称不再合适(它不再受互斥保护).如果是这样,甚至有必要让不同的读者使用相同的互斥锁?
C++ 11有std :: condition_variable,它的等待函数是
template< class Predicate >
void wait( std::unique_lock<std::mutex>& lock, Predicate pred );
Run Code Online (Sandbox Code Playgroud)
它需要一个互斥量.
据我所知 - 它的notify_one可以在没有同步的情况下调用(我知道惯用的方法是将它与互斥锁一起使用).
我有一个对象,其已经在内部同步 -所以我并不需要一个互斥量来保护它.一个线程应该等待与该对象关联的某个事件,并且其他线程将被通知.
如何在C++ 11中没有互斥的情况下进行此类通知?即使用condition_variable很容易,但它需要一个互斥量.我想过使用假的互斥锁类型,但是在等待界面中固定了std :: mutex.
一个选项是轮询std :: atomic_flag + sleep,但我不喜欢睡觉.
我需要同步std::condition_variable/condition_variable_any::notify_one吗?
据我所知,如果通知丢失是可以接受的 - 可以调用notify_one不受保护(例如通过互斥).
例如,我看到了以下使用模式(抱歉,不记得在哪里):
{
{
lock_guard<mutex> l(m);
// do work
}
c.notify_one();
}
Run Code Online (Sandbox Code Playgroud)
但是,我检查了libstdc ++来源,我看到:
condition_variable :: notify_one
void condition_variable::notify_one() noexcept
{
int __e = __gthread_cond_signal(&_M_cond);
// XXX not in spec
// EINVAL
if (__e)
__throw_system_error(__e);
}
Run Code Online (Sandbox Code Playgroud)
和condition_variable_any :: notify_one:
void condition_variable_any::notify_one() noexcept
{
lock_guard<mutex> __lock(_M_mutex);
_M_cond.notify_one();
}
Run Code Online (Sandbox Code Playgroud)
这里是condition_variable_any的布局:
class condition_variable_any
{
condition_variable _M_cond;
mutex _M_mutex;
// data end
Run Code Online (Sandbox Code Playgroud)
即它只是condition_variable + mutex周围的薄包装.
所以,问题:
notify_one的互斥体的任一condition_variable_any或condition_variable?