2

经典的生产者消费者问题中。itemCount == BUFFER_SIZE当AMD 宕机时再次唤醒时,生产者会睡觉。但是一旦itemCount长大,生产者线程就会进入睡眠状态。它怎么知道itemCount已经下降并且需要下降wakeup

4

3 回答 3

2

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

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

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

void SynchronizedQueue::push(Item const &i)
{
    pthread_mutex_lock(&mutex);

    // queue is full, so wait for consumer
    while (queue.size() == BUFFER_SIZE)
        pthread_cond_wait(&condition, &mutex);

    // when we get here, the queue has space
    this->queue.push_back(i);

    // make sure we wake a sleeping consumer
    if (queue.size() == 1)
        pthread_cond_signal(&condition);

    pthread_mutex_unlock(&mutex);
}

以及消费者使用的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;
}
于 2012-06-24T18:46:07.870 回答
1

你需要条件变量。

条件变量的典型用法是:

//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

whereCheckCondition是一个检查条件的函数(或函子)(例如,何时醒来)。当它被虚假唤醒时,它被wait()函数内部调用,如果条件尚未满足,则函数再次休眠。在睡觉之前,原子地释放互斥锁。wait()wait()


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

如果您的编译器不支持它,并且您使用的是 win32 线程,请查看以下内容:

这是一个完整例子。

如果您使用 POSIX 线程,请查看以下内容:


你可以在这里看到我conditional_variable使用 win32 原语的实现:

向下滚动,先看看它的实现,再看看并发队列实现中的用法。

于 2012-06-24T18:36:46.283 回答
0

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

传统上,PC 队列由一个简单的非线程安全队列、一个用于保护其索引/指针的互斥体和两个信号量构成——一个初始化为 0 以计算队列中的项目,一个初始化为 [队列大小] 以计算空白空间. 生产者在“emptySpace”上等待,当它收到信号时,锁定互斥体,将对象入队,锁定互斥体并发出“itemCount”信号。消费者等待“itemCount”,当它收到信号时,锁定互斥体,使对象出队,锁定互斥体并发出“emptySpace”信号。

于 2012-06-24T19:51:17.503 回答