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