Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/142.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++ 使用boost线程和循环缓冲区挂起的生产者/消费者_C++_Boost_Producer Consumer - Fatal编程技术网

C++ 使用boost线程和循环缓冲区挂起的生产者/消费者

C++ 使用boost线程和循环缓冲区挂起的生产者/消费者,c++,boost,producer-consumer,C++,Boost,Producer Consumer,我想出来了。我犯了一个愚蠢的错误,我实际上并没有从队列中删除元素,我只是在读取第一个元素。我修改了代码,下面的代码不起作用。谢谢大家的帮助 我正在尝试使用boost实现生产者-消费者问题,这实际上是一个更大项目的一部分。我已经实现了一个程序,从互联网上的例子,甚至一些帮助,我在这里找到。然而,目前我的代码只是挂起。基于一些好的建议,我决定使用boost ciruclar缓冲区在生产者和消费者之间保存数据。那里有很多类似的代码,我能够从中汇集想法,自己写一些东西。然而,我似乎仍然有和以前一样的问题

我想出来了。我犯了一个愚蠢的错误,我实际上并没有从队列中删除元素,我只是在读取第一个元素。我修改了代码,下面的代码不起作用。谢谢大家的帮助

我正在尝试使用boost实现生产者-消费者问题,这实际上是一个更大项目的一部分。我已经实现了一个程序,从互联网上的例子,甚至一些帮助,我在这里找到。然而,目前我的代码只是挂起。基于一些好的建议,我决定使用boost ciruclar缓冲区在生产者和消费者之间保存数据。那里有很多类似的代码,我能够从中汇集想法,自己写一些东西。然而,我似乎仍然有和以前一样的问题(我的程序只是挂起)。我想我没有犯和以前一样的错误

我的代码如下所示,我已经取出了我以前的代码,在那里我只是我自己的单链接列表

缓冲区标头:

#ifndef PCDBUFFER_H
#define PCDBUFFER_H

#include <pcl/io/pcd_io.h>
#include <boost/thread/mutex.hpp>
#include <boost/thread/condition.hpp>
#include <boost/circular_buffer.hpp>

class pcdBuffer
{
    public:
        pcdBuffer(int buffSize);
        void put(int data);
        int get();
        bool isFull();
        bool isEmpty();
        int getSize();
        int getCapacity();
    private:
        boost::mutex bmutex;
        boost::condition_variable buffEmpty;
        boost::condition_variable buffFull;
        boost::circular_buffer<int> buffer;
};


#endif
\ifndef PCDBUFFER\u H
#定义PCDBUFFER_H
#包括
#包括
#包括
#包括
pcdBuffer类
{
公众:
pcdBuffer(int buffSize);
无效看跌期权(整数数据);
int get();
bool已满();
bool是空的();
int getSize();
int getCapacity();
私人:
boost::互斥体bmutex;
boost::条件_变量buffEmpty;
boost::条件_变量buffFull;
boost::循环缓冲区;
};
#恩迪夫
缓冲源(仅相关部分):

#包括“pcdBuffer.h”
#包括
//boost::mutex io_mutex;
pcdBuffer::pcdBuffer(int buffSize)
{
缓冲区。设置_容量(buffSize);
}
void pcdBuffer::put(int数据)
{
{
boost::mutex::作用域锁定buffLock(bmutex);
while(buffer.full())
{

std::cout首先,您可以将
std::list
包装到
pcdQueue
中,而不是编写自己的列表,而不是编写自己的列表。这是正确的,
std::list
不是线程安全的,但是您在类中提供了必要的同步原语

程序挂起的原因: 您保留锁并填充队列,直到队列已满。您通过
notify_one
通知消费者是无用的,因为消费者将再次正确锁定,因为互斥锁已经被(生产者中的锁)占用

当您通过等待
条件变量
最终释放锁(队列已满)时,您不会唤醒消费者,因此消费者和生产者都被阻止,程序挂起

将其更改为:

void pcdQueue::produce()
{
    int i=0;
    while(true)
    {
        {
            boost::mutex::scoped_lock lock(qmutex);
            while( ! qlen < buffSize ) {
                std::cout << "Queue is full" << std::endl;
                full.wait(lock);
            }

            enqueue(i); // or myList.push_back(i) if you switch to std::list
        }

        empty.notify_one();


    }
}
pcdFrame* pcdQueue::consume()
{
    pcdFrame *frame;

    {
        boost::mutex::scoped_lock lock(qmutex);
        while( qlen == 0 ) {
            std::cout << "Queue is empty" << std::endl;
            empty.wait(lock);
        }

        frame = dequeue();
    }
    full.notify_one();

    return frame;
}
一般来说,请注意,只有在有人在等待时,通知才会生效。否则,通知将“丢失”。此外,请注意,在调用
notify\u one
(事实上,这可能会导致额外的上下文切换开销,因为您唤醒另一个线程,该线程将等待当前(仍然)被您锁定的互斥锁。因此,首先释放互斥锁,然后告诉另一个线程继续


请注意,两个线程都无限运行,因此主程序在第一次
join()时仍将挂起
并且永远不会退出。您可以在
循环时在
中包含一个停止标志,以通知线程完成。

首先,您可以将
std::list
包装在
pcdQueue
中,而不是编写自己的。正确的是,
std::list
不是线程safe原样,但您仍然在类中提供了必要的同步原语

程序挂起的原因: 您保留锁并填充队列,直到队列已满。您通过
notify_one
通知消费者是无用的,因为消费者将再次正确锁定,因为互斥锁已经被(生产者中的锁)占用

当您通过等待
条件变量
最终释放锁(队列已满)时,您不会唤醒消费者,因此消费者和生产者都被阻止,程序挂起

将其更改为:

void pcdQueue::produce()
{
    int i=0;
    while(true)
    {
        {
            boost::mutex::scoped_lock lock(qmutex);
            while( ! qlen < buffSize ) {
                std::cout << "Queue is full" << std::endl;
                full.wait(lock);
            }

            enqueue(i); // or myList.push_back(i) if you switch to std::list
        }

        empty.notify_one();


    }
}
pcdFrame* pcdQueue::consume()
{
    pcdFrame *frame;

    {
        boost::mutex::scoped_lock lock(qmutex);
        while( qlen == 0 ) {
            std::cout << "Queue is empty" << std::endl;
            empty.wait(lock);
        }

        frame = dequeue();
    }
    full.notify_one();

    return frame;
}
一般来说,请注意,只有在有人在等待时,通知才会生效。否则,通知将“丢失”。此外,请注意,在调用
notify\u one
(事实上,这可能会导致额外的上下文切换开销,因为您唤醒另一个线程,该线程将等待当前(仍然)被您锁定的互斥锁。因此,首先释放互斥锁,然后告诉另一个线程继续


请注意,两个线程都无限运行,因此主程序在第一次
join()时仍将挂起
并且永远不会退出。您可以在
循环时在
中包含一个停止标志,以通知线程完成。

Boost现在在其无锁部分提供了生产者/消费者队列类型,该队列基本上是无锁的,尽管如果队列已满,它可能会锁定

您可以在此处找到文档:


这是一个相当新的添加,所以我认为它还不是许多标准包的一部分。另一方面,它看起来主要是标题,所有这些都依赖于boost中长期存在的相当低级别的系统内容。

boost现在在其无锁部分提供了生产者/消费者队列类型,虽然它是如果队列已满,则可能会锁定

您可以在此处找到文档:


这是最近添加的,所以我不认为它是许多标准包的一部分。另一方面,这看起来像是标题,所有这些都依赖于boost中很长一段时间以来相当低级的系统内容。

我遇到了相同的挂起问题。多亏了Johannes的回答,我才能够使它完全工作。Howe但是,我不得不使用 已满。等待(锁定、增压::c