Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/141.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 经典生产者消费者线程_C++_Multithreading_Producer Consumer - Fatal编程技术网

C++ 经典生产者消费者线程

C++ 经典生产者消费者线程,c++,multithreading,producer-consumer,C++,Multithreading,Producer Consumer,在公园里。当amd在下降时再次唤醒时,itemCount==BUFFER\u SIZEamd时,生产者睡眠。但一旦itemCount长大,生产者线程就会进入睡眠状态。它如何知道itemCount已下降,需要唤醒?您需要条件变量 条件变量的典型用法如下: //lock the mutex first! scoped_lock myLock(myMutex); //wait till a condition is met myConditionalVariable.wait(myLock, Ch

在公园里。当amd在下降时再次唤醒时,
itemCount==BUFFER\u SIZE
amd时,生产者睡眠。但一旦
itemCount
长大,生产者线程就会进入睡眠状态。它如何知道
itemCount
已下降,需要
唤醒

您需要条件变量

条件变量的典型用法如下:

//lock the mutex first!
scoped_lock myLock(myMutex); 

//wait till a condition is met
myConditionalVariable.wait(myLock, CheckCondition);

//Execute this code only if the condition is met
其中,
CheckCondition
是一个函数(或函子),用于检查条件(例如,关于何时唤醒)。当它意外唤醒时,
wait()
函数在内部调用它,如果条件尚未满足,
wait()
函数将再次休眠。睡觉前,
wait()
会自动释放互斥锁


如果您的编译器支持C++11引入的
std::conditional
,那么您可以查看以下详细信息:

如果您的编译器不支持它,而您使用的是win32线程,请参见以下内容:

这是一个完整的例子

如果您使用POSIX线程,请参见以下内容:


您可以在这里看到我使用win32原语实现的
条件_变量


向下滚动,首先查看它的实现,然后查看并发队列实现中的用法。

在伪代码中,生产者类似于:

void producer_thread()
{
    while(true)
        queue.push( produce() );
}

考虑队列推送方法(我在这里使用了pType,但是同样的逻辑适用于其他库)

以及消费者使用的pop方法:

Item SynchronizedQueue::pop()
{
    pthread_mutex_lock(&mutex);

    // wait for something to do
    while (queue.size() == 0)
        pthread_cond_wait(&condition, &mutex);

    // if we get here, we have some work
    Item tmp = queue.front();

    // make sure we wake a sleeping producer
    if (queue.size() == BUFFER_SIZE)
        pthread_cond_signal(&condition)

    queue.pop_front();
    pthread_mutex_unlock(&mutex);
    return tmp;
}

它不需要知道——当消费者发出信号时,操作系统会唤醒它。在P-C队列代码中,生产者将对某些OS同步原语进行wait()调用。在使用者线程释放空间并向OS synchro对象发送信号之前,此调用不会返回(除非有故障的OS“支持”虚假唤醒),此时等待的生产者线程将准备就绪,如果有可用的内核,则立即运行-wait()调用将返回


传统上,p-C队列是由一个简单的非线程安全队列、一个保护其索引/指针的互斥体和两个信号量构成的——一个初始化为0以计数队列中的项目,另一个初始化为[queue size]以计数空空间。生产者等待“emptySpace”,当它收到信号时,锁定互斥体,将对象排队,锁定互斥体并发出“itemCount”信号。消费者等待“itemCount”,当它收到信号时,锁定互斥锁,将对象出列,锁定互斥锁并发出“emptySpace”信号。

您如何定义
条件
?正如纳瓦兹所说,这是条件变量的标准用法。因此,在这段代码中,它将被声明为
pthread\u cond\t condition
。不过,我可以用C++11的
std::condition\u变量和
std::unique\u lock
实现完全相同的逻辑;这是链接的wikipedia页面的“使用监视器”部分中描述的逻辑。
Item SynchronizedQueue::pop()
{
    pthread_mutex_lock(&mutex);

    // wait for something to do
    while (queue.size() == 0)
        pthread_cond_wait(&condition, &mutex);

    // if we get here, we have some work
    Item tmp = queue.front();

    // make sure we wake a sleeping producer
    if (queue.size() == BUFFER_SIZE)
        pthread_cond_signal(&condition)

    queue.pop_front();
    pthread_mutex_unlock(&mutex);
    return tmp;
}