C++ 读线程和写线程之间的同步(通过限制写数据的大小)
我正在尝试编写一个包含以下组件的测试台-C++ 读线程和写线程之间的同步(通过限制写数据的大小),c++,multithreading,synchronization,queue,C++,Multithreading,Synchronization,Queue,我正在尝试编写一个包含以下组件的测试台- #include <boost/thread.hpp> #include <boost/thread/exceptions.hpp> #include <boost/thread/mutex.hpp> #include <boost/thread/condition_variable.hpp> #include <iostream> #include <queue> #include
#include <boost/thread.hpp>
#include <boost/thread/exceptions.hpp>
#include <boost/thread/mutex.hpp>
#include <boost/thread/condition_variable.hpp>
#include <iostream>
#include <queue>
#include <iterator>
#include <algorithm>
using namespace boost;
using namespace std;
///////////////////////////////////////////////////////////
//A transaction is an electrical signal with a value(data)
//in discreet time(t_id)
///////////////////////////////////////////////////////////
typedef struct transaction{
float data;
//the t_id is the transaction id; this is used to
//synchronize the data being generated by the producer
//threads
int t_id;
}sample__;
/////////////////////////////////////////////////////////////
//Thread safe queue; from which the connector is derived;
//it guarantees data coherency...
/////////////////////////////////////////////////////////////
template<class T>
class thread_safe_queue{
public:
typedef typename std::queue<T>::container_type container_type;
typedef typename std::queue<T>::size_type size_type;
typedef typename std::queue<T>::value_type value_type;
thread_safe_queue(){ cout << "Depth :: " << depth << endl;}
~thread_safe_queue(){}
private:
mutable boost::mutex mutex_;
boost::condition_variable cond_;
std::queue<T> queue_;
public:
void push(const T& t){
{
boost::mutex::scoped_lock lock(mutex_);
cout << "Write::Queue Size :: "<< thread_safe_queue<sample__>::size() << "Depth :: " << depth << endl;
//wait for condition
while(size() > depth){
cout <<"Write Stall...."<<endl;
cond_.wait(lock);
}
queue_.push(t);
//cout << "Push @ " << t.t_id << " * " << t.data << endl;
}
cond_.notify_one(); //notify other thread of addition to queue
}
void pop(T& t){
boost::mutex::scoped_lock lock(mutex_);
cout << "Read::Queue Size :: "<< thread_safe_queue<sample__>::size() << "Depth :: " << depth << endl;
//wait for condition
while(queue_.empty()){
cout << "Read Stall...."<<endl;
cond_.wait(lock);
}
//cout << " Pop @ " << t.t_id << " * " << t.data << endl;
t = queue_.front();
queue_.pop();
}
size_type size() const {
boost::mutex::scoped_lock lock(mutex_);
return queue_.size();
}
protected:
int depth;
}; //class thread_safe_queue
//////////////////////////////////////////////////////////////
//The connector class models a physical unidirectional attachment
//////////////////////////////////////////////////////////////
class connector : public thread_safe_queue<sample__> {
public:
connector(int depth) : sample_cnt(0){
thread_safe_queue<sample__>::depth = depth;
cout << "Depth :: " << depth << endl;
}
~connector(){}
//*****************************************************
//write method
//*****************************************************
void write_data(sample__ data_sample)
{
//cout << "Write::Queue Size :: "<< thread_safe_queue<sample__>::size() << endl;
thread_safe_queue<sample__>::push(data_sample);
}
//******************************************************
//read method
//******************************************************
sample__ read_data(void)
{
sample__ sample;
//cout << "Read::Queue Size :: "<< thread_safe_queue<sample__>::size() << endl;
thread_safe_queue<sample__>::pop(sample);
return(sample);
}
private:
int sample_cnt;
boost::condition_variable cond_;
mutable boost::mutex mutex_;
};
/////////////////////////////////////////////////////////////////
//Data Source
/////////////////////////////////////////////////////////////////
class data_src{
public:
connector *this_foo;
data_src(connector *foo) : this_foo(foo){}
~data_src(){}
void write(connector *foo)
{
sample__ in;
int ii=0;
while(1){
in.data = rand();
in.t_id = ii;
this_foo->write_data(in);
ii++;
//sleep(2);
}
}
};//class data_src
////////////////////////////////////////////////////////////////
//Data Sink
////////////////////////////////////////////////////////////////
class data_sink{
public:
connector *this_foo;
data_sink(connector *foo) : this_foo(foo){}
~data_sink(){}
void read(connector *foo)
{
sample__ out;
while(1){
out=this_foo->read_data();
}
}
};
class run : public boost::thread
{
};
//////////////////////////////////////////////////////////////////
//Testbed.....
//////////////////////////////////////////////////////////////////
int main(int argc, char**argv)
{
connector *foo = new connector(5);
data_src generator(foo);
data_sink terminal(foo);
boost::thread __write;
boost::thread __read;
__write = boost::thread(&data_src::write, &generator, foo);
__read = boost::thread(&data_sink::read, &terminal, foo);
__read.join();
__write.join();
}
#include <boost/thread.hpp>
#include <boost/thread/exceptions.hpp>
#include <boost/thread/mutex.hpp>
#include <boost/thread/condition_variable.hpp>
#include <iostream>
#include <queue>
#include <iterator>
#include <algorithm>
using namespace boost;
using namespace std;
///////////////////////////////////////////////////////////
//A transaction is an electrical signal with a value(data)
//in discreet time(t_id)
///////////////////////////////////////////////////////////
typedef struct transaction{
float data;
//the t_id is the transaction id; this is used to
//synchronize the data being generated by the producer
//threads
int t_id;
}sample__;
/////////////////////////////////////////////////////////////
//Thread safe queue; from which the connector is derived;
//it guarantees data coherency...
/////////////////////////////////////////////////////////////
template<class T>
class thread_safe_queue{
public:
typedef typename std::queue<T>::container_type container_type;
typedef typename std::queue<T>::size_type size_type;
typedef typename std::queue<T>::value_type value_type;
thread_safe_queue(){ cout << "Depth :: " << depth << endl;}
~thread_safe_queue(){}
private:
mutable boost::mutex mutex_;
boost::condition_variable cond_;
std::queue<T> queue_;
public:
void push(const T& t){
{
boost::mutex::scoped_lock lock(mutex_);
cout << "Write::Queue Size :: "<< thread_safe_queue<sample__>::size() << "Depth :: " << depth << endl;
//wait for condition
while(size() > depth){
cout <<"Write Stall...."<<endl;
cond_.wait(lock);
}
queue_.push(t);
//cout << "Push @ " << t.t_id << " * " << t.data << endl;
}
cond_.notify_one(); //notify other thread of addition to queue
}
void pop(T& t){
boost::mutex::scoped_lock lock(mutex_);
cout << "Read::Queue Size :: "<< thread_safe_queue<sample__>::size() << "Depth :: " << depth << endl;
//wait for condition
while(queue_.empty()){
cout << "Read Stall...."<<endl;
cond_.wait(lock);
}
//cout << " Pop @ " << t.t_id << " * " << t.data << endl;
t = queue_.front();
queue_.pop();
}
size_type size() const {
boost::mutex::scoped_lock lock(mutex_);
return queue_.size();
}
protected:
int depth;
}; //class thread_safe_queue
//////////////////////////////////////////////////////////////
//The connector class models a physical unidirectional attachment
//////////////////////////////////////////////////////////////
class connector : public thread_safe_queue<sample__> {
public:
connector(int depth) : sample_cnt(0){
thread_safe_queue<sample__>::depth = depth;
cout << "Depth :: " << depth << endl;
}
~connector(){}
//*****************************************************
//write method
//*****************************************************
void write_data(sample__ data_sample)
{
//cout << "Write::Queue Size :: "<< thread_safe_queue<sample__>::size() << endl;
thread_safe_queue<sample__>::push(data_sample);
}
//******************************************************
//read method
//******************************************************
sample__ read_data(void)
{
sample__ sample;
//cout << "Read::Queue Size :: "<< thread_safe_queue<sample__>::size() << endl;
thread_safe_queue<sample__>::pop(sample);
return(sample);
}
private:
int sample_cnt;
boost::condition_variable cond_;
mutable boost::mutex mutex_;
};
/////////////////////////////////////////////////////////////////
//Data Source
/////////////////////////////////////////////////////////////////
class data_src{
public:
connector *this_foo;
data_src(connector *foo) : this_foo(foo){}
~data_src(){}
void write(connector *foo)
{
sample__ in;
int ii=0;
while(1){
in.data = rand();
in.t_id = ii;
this_foo->write_data(in);
ii++;
//sleep(2);
}
}
};//class data_src
////////////////////////////////////////////////////////////////
//Data Sink
////////////////////////////////////////////////////////////////
class data_sink{
public:
connector *this_foo;
data_sink(connector *foo) : this_foo(foo){}
~data_sink(){}
void read(connector *foo)
{
sample__ out;
while(1){
out=this_foo->read_data();
}
}
};
class run : public boost::thread
{
};
//////////////////////////////////////////////////////////////////
//Testbed.....
//////////////////////////////////////////////////////////////////
int main(int argc, char**argv)
{
connector *foo = new connector(5);
data_src generator(foo);
data_sink terminal(foo);
boost::thread __write;
boost::thread __read;
__write = boost::thread(&data_src::write, &generator, foo);
__read = boost::thread(&data_sink::read, &terminal, foo);
__read.join();
__write.join();
}
#include <boost/thread.hpp>
#include <boost/thread/exceptions.hpp>
#include <boost/thread/mutex.hpp>
#include <boost/thread/condition_variable.hpp>
#include <iostream>
#include <queue>
#include <iterator>
#include <algorithm>
using namespace boost;
using namespace std;
///////////////////////////////////////////////////////////
//A transaction is an electrical signal with a value(data)
//in discreet time(t_id)
///////////////////////////////////////////////////////////
typedef struct transaction{
float data;
//the t_id is the transaction id; this is used to
//synchronize the data being generated by the producer
//threads
int t_id;
}sample__;
/////////////////////////////////////////////////////////////
//Thread safe queue; from which the connector is derived;
//it guarantees data coherency...
/////////////////////////////////////////////////////////////
template<class T>
class thread_safe_queue{
public:
typedef typename std::queue<T>::container_type container_type;
typedef typename std::queue<T>::size_type size_type;
typedef typename std::queue<T>::value_type value_type;
thread_safe_queue(){ cout << "Depth :: " << depth << endl;}
~thread_safe_queue(){}
private:
mutable boost::mutex mutex_;
boost::condition_variable cond_;
std::queue<T> queue_;
public:
void push(const T& t){
{
boost::mutex::scoped_lock lock(mutex_);
cout << "Write::Queue Size :: "<< thread_safe_queue<sample__>::size() << "Depth :: " << depth << endl;
//wait for condition
while(size() > depth){
cout <<"Write Stall...."<<endl;
cond_.wait(lock);
}
queue_.push(t);
//cout << "Push @ " << t.t_id << " * " << t.data << endl;
}
cond_.notify_one(); //notify other thread of addition to queue
}
void pop(T& t){
boost::mutex::scoped_lock lock(mutex_);
cout << "Read::Queue Size :: "<< thread_safe_queue<sample__>::size() << "Depth :: " << depth << endl;
//wait for condition
while(queue_.empty()){
cout << "Read Stall...."<<endl;
cond_.wait(lock);
}
//cout << " Pop @ " << t.t_id << " * " << t.data << endl;
t = queue_.front();
queue_.pop();
}
size_type size() const {
boost::mutex::scoped_lock lock(mutex_);
return queue_.size();
}
protected:
int depth;
}; //class thread_safe_queue
//////////////////////////////////////////////////////////////
//The connector class models a physical unidirectional attachment
//////////////////////////////////////////////////////////////
class connector : public thread_safe_queue<sample__> {
public:
connector(int depth) : sample_cnt(0){
thread_safe_queue<sample__>::depth = depth;
cout << "Depth :: " << depth << endl;
}
~connector(){}
//*****************************************************
//write method
//*****************************************************
void write_data(sample__ data_sample)
{
//cout << "Write::Queue Size :: "<< thread_safe_queue<sample__>::size() << endl;
thread_safe_queue<sample__>::push(data_sample);
}
//******************************************************
//read method
//******************************************************
sample__ read_data(void)
{
sample__ sample;
//cout << "Read::Queue Size :: "<< thread_safe_queue<sample__>::size() << endl;
thread_safe_queue<sample__>::pop(sample);
return(sample);
}
private:
int sample_cnt;
boost::condition_variable cond_;
mutable boost::mutex mutex_;
};
/////////////////////////////////////////////////////////////////
//Data Source
/////////////////////////////////////////////////////////////////
class data_src{
public:
connector *this_foo;
data_src(connector *foo) : this_foo(foo){}
~data_src(){}
void write(connector *foo)
{
sample__ in;
int ii=0;
while(1){
in.data = rand();
in.t_id = ii;
this_foo->write_data(in);
ii++;
//sleep(2);
}
}
};//class data_src
////////////////////////////////////////////////////////////////
//Data Sink
////////////////////////////////////////////////////////////////
class data_sink{
public:
connector *this_foo;
data_sink(connector *foo) : this_foo(foo){}
~data_sink(){}
void read(connector *foo)
{
sample__ out;
while(1){
out=this_foo->read_data();
}
}
};
class run : public boost::thread
{
};
//////////////////////////////////////////////////////////////////
//Testbed.....
//////////////////////////////////////////////////////////////////
int main(int argc, char**argv)
{
connector *foo = new connector(5);
data_src generator(foo);
data_sink terminal(foo);
boost::thread __write;
boost::thread __read;
__write = boost::thread(&data_src::write, &generator, foo);
__read = boost::thread(&data_sink::read, &terminal, foo);
__read.join();
__write.join();
}
exe:
g++-g-o$(EXE)$(EXE).cpp-I/home/rmitra1/Eval/boost/include/-L\/home/rmitra1/Eval/boost/lib-lboost\u线程-lpthread-lboost\u系统
#include <boost/thread.hpp>
#include <boost/thread/exceptions.hpp>
#include <boost/thread/mutex.hpp>
#include <boost/thread/condition_variable.hpp>
#include <iostream>
#include <queue>
#include <iterator>
#include <algorithm>
using namespace boost;
using namespace std;
///////////////////////////////////////////////////////////
//A transaction is an electrical signal with a value(data)
//in discreet time(t_id)
///////////////////////////////////////////////////////////
typedef struct transaction{
float data;
//the t_id is the transaction id; this is used to
//synchronize the data being generated by the producer
//threads
int t_id;
}sample__;
/////////////////////////////////////////////////////////////
//Thread safe queue; from which the connector is derived;
//it guarantees data coherency...
/////////////////////////////////////////////////////////////
template<class T>
class thread_safe_queue{
public:
typedef typename std::queue<T>::container_type container_type;
typedef typename std::queue<T>::size_type size_type;
typedef typename std::queue<T>::value_type value_type;
thread_safe_queue(){ cout << "Depth :: " << depth << endl;}
~thread_safe_queue(){}
private:
mutable boost::mutex mutex_;
boost::condition_variable cond_;
std::queue<T> queue_;
public:
void push(const T& t){
{
boost::mutex::scoped_lock lock(mutex_);
cout << "Write::Queue Size :: "<< thread_safe_queue<sample__>::size() << "Depth :: " << depth << endl;
//wait for condition
while(size() > depth){
cout <<"Write Stall...."<<endl;
cond_.wait(lock);
}
queue_.push(t);
//cout << "Push @ " << t.t_id << " * " << t.data << endl;
}
cond_.notify_one(); //notify other thread of addition to queue
}
void pop(T& t){
boost::mutex::scoped_lock lock(mutex_);
cout << "Read::Queue Size :: "<< thread_safe_queue<sample__>::size() << "Depth :: " << depth << endl;
//wait for condition
while(queue_.empty()){
cout << "Read Stall...."<<endl;
cond_.wait(lock);
}
//cout << " Pop @ " << t.t_id << " * " << t.data << endl;
t = queue_.front();
queue_.pop();
}
size_type size() const {
boost::mutex::scoped_lock lock(mutex_);
return queue_.size();
}
protected:
int depth;
}; //class thread_safe_queue
//////////////////////////////////////////////////////////////
//The connector class models a physical unidirectional attachment
//////////////////////////////////////////////////////////////
class connector : public thread_safe_queue<sample__> {
public:
connector(int depth) : sample_cnt(0){
thread_safe_queue<sample__>::depth = depth;
cout << "Depth :: " << depth << endl;
}
~connector(){}
//*****************************************************
//write method
//*****************************************************
void write_data(sample__ data_sample)
{
//cout << "Write::Queue Size :: "<< thread_safe_queue<sample__>::size() << endl;
thread_safe_queue<sample__>::push(data_sample);
}
//******************************************************
//read method
//******************************************************
sample__ read_data(void)
{
sample__ sample;
//cout << "Read::Queue Size :: "<< thread_safe_queue<sample__>::size() << endl;
thread_safe_queue<sample__>::pop(sample);
return(sample);
}
private:
int sample_cnt;
boost::condition_variable cond_;
mutable boost::mutex mutex_;
};
/////////////////////////////////////////////////////////////////
//Data Source
/////////////////////////////////////////////////////////////////
class data_src{
public:
connector *this_foo;
data_src(connector *foo) : this_foo(foo){}
~data_src(){}
void write(connector *foo)
{
sample__ in;
int ii=0;
while(1){
in.data = rand();
in.t_id = ii;
this_foo->write_data(in);
ii++;
//sleep(2);
}
}
};//class data_src
////////////////////////////////////////////////////////////////
//Data Sink
////////////////////////////////////////////////////////////////
class data_sink{
public:
connector *this_foo;
data_sink(connector *foo) : this_foo(foo){}
~data_sink(){}
void read(connector *foo)
{
sample__ out;
while(1){
out=this_foo->read_data();
}
}
};
class run : public boost::thread
{
};
//////////////////////////////////////////////////////////////////
//Testbed.....
//////////////////////////////////////////////////////////////////
int main(int argc, char**argv)
{
connector *foo = new connector(5);
data_src generator(foo);
data_sink terminal(foo);
boost::thread __write;
boost::thread __read;
__write = boost::thread(&data_src::write, &generator, foo);
__read = boost::thread(&data_sink::read, &terminal, foo);
__read.join();
__write.join();
}
-------------------------程序代码如下------------------------------------------
#include <boost/thread.hpp>
#include <boost/thread/exceptions.hpp>
#include <boost/thread/mutex.hpp>
#include <boost/thread/condition_variable.hpp>
#include <iostream>
#include <queue>
#include <iterator>
#include <algorithm>
using namespace boost;
using namespace std;
///////////////////////////////////////////////////////////
//A transaction is an electrical signal with a value(data)
//in discreet time(t_id)
///////////////////////////////////////////////////////////
typedef struct transaction{
float data;
//the t_id is the transaction id; this is used to
//synchronize the data being generated by the producer
//threads
int t_id;
}sample__;
/////////////////////////////////////////////////////////////
//Thread safe queue; from which the connector is derived;
//it guarantees data coherency...
/////////////////////////////////////////////////////////////
template<class T>
class thread_safe_queue{
public:
typedef typename std::queue<T>::container_type container_type;
typedef typename std::queue<T>::size_type size_type;
typedef typename std::queue<T>::value_type value_type;
thread_safe_queue(){ cout << "Depth :: " << depth << endl;}
~thread_safe_queue(){}
private:
mutable boost::mutex mutex_;
boost::condition_variable cond_;
std::queue<T> queue_;
public:
void push(const T& t){
{
boost::mutex::scoped_lock lock(mutex_);
cout << "Write::Queue Size :: "<< thread_safe_queue<sample__>::size() << "Depth :: " << depth << endl;
//wait for condition
while(size() > depth){
cout <<"Write Stall...."<<endl;
cond_.wait(lock);
}
queue_.push(t);
//cout << "Push @ " << t.t_id << " * " << t.data << endl;
}
cond_.notify_one(); //notify other thread of addition to queue
}
void pop(T& t){
boost::mutex::scoped_lock lock(mutex_);
cout << "Read::Queue Size :: "<< thread_safe_queue<sample__>::size() << "Depth :: " << depth << endl;
//wait for condition
while(queue_.empty()){
cout << "Read Stall...."<<endl;
cond_.wait(lock);
}
//cout << " Pop @ " << t.t_id << " * " << t.data << endl;
t = queue_.front();
queue_.pop();
}
size_type size() const {
boost::mutex::scoped_lock lock(mutex_);
return queue_.size();
}
protected:
int depth;
}; //class thread_safe_queue
//////////////////////////////////////////////////////////////
//The connector class models a physical unidirectional attachment
//////////////////////////////////////////////////////////////
class connector : public thread_safe_queue<sample__> {
public:
connector(int depth) : sample_cnt(0){
thread_safe_queue<sample__>::depth = depth;
cout << "Depth :: " << depth << endl;
}
~connector(){}
//*****************************************************
//write method
//*****************************************************
void write_data(sample__ data_sample)
{
//cout << "Write::Queue Size :: "<< thread_safe_queue<sample__>::size() << endl;
thread_safe_queue<sample__>::push(data_sample);
}
//******************************************************
//read method
//******************************************************
sample__ read_data(void)
{
sample__ sample;
//cout << "Read::Queue Size :: "<< thread_safe_queue<sample__>::size() << endl;
thread_safe_queue<sample__>::pop(sample);
return(sample);
}
private:
int sample_cnt;
boost::condition_variable cond_;
mutable boost::mutex mutex_;
};
/////////////////////////////////////////////////////////////////
//Data Source
/////////////////////////////////////////////////////////////////
class data_src{
public:
connector *this_foo;
data_src(connector *foo) : this_foo(foo){}
~data_src(){}
void write(connector *foo)
{
sample__ in;
int ii=0;
while(1){
in.data = rand();
in.t_id = ii;
this_foo->write_data(in);
ii++;
//sleep(2);
}
}
};//class data_src
////////////////////////////////////////////////////////////////
//Data Sink
////////////////////////////////////////////////////////////////
class data_sink{
public:
connector *this_foo;
data_sink(connector *foo) : this_foo(foo){}
~data_sink(){}
void read(connector *foo)
{
sample__ out;
while(1){
out=this_foo->read_data();
}
}
};
class run : public boost::thread
{
};
//////////////////////////////////////////////////////////////////
//Testbed.....
//////////////////////////////////////////////////////////////////
int main(int argc, char**argv)
{
connector *foo = new connector(5);
data_src generator(foo);
data_sink terminal(foo);
boost::thread __write;
boost::thread __read;
__write = boost::thread(&data_src::write, &generator, foo);
__read = boost::thread(&data_sink::read, &terminal, foo);
__read.join();
__write.join();
}
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
使用名称空间boost;
使用名称空间std;
///////////////////////////////////////////////////////////
//事务是具有值(数据)的电信号
//在谨慎的时间(t_id)
///////////////////////////////////////////////////////////
typedef结构事务{
浮动数据;
//t_id是事务id;用于
//同步生产者正在生成的数据
//线程
int t_id;
}样品;
/////////////////////////////////////////////////////////////
//线程安全队列;连接器从中派生;
//它保证了数据的一致性。。。
/////////////////////////////////////////////////////////////
模板
类线程安全队列{
公众:
typedef typename std::queue::container\u type container\u type;
typedef typename std::queue::size\u type size\u type;
typedef typename std::queue::value_type value_type;
线程安全队列(){为什么连接器类有自己的专用互斥体?如果互斥体要保护队列,那么应该只有其中一个。将队列互斥体访问更改为protected并在连接器中继承它。我看不出连接器弹出信号是如何发出一个在队列已满时被阻止的推送信号以恢复推送的?而且,下划线刺痛了我的眼睛:)嗨,James,我的坏消息是,我修复了基类,使其只有一个互斥体来保护队列。因此,互斥体现在对派生类(连接器)完全隐藏。push和pop方法现在看起来是这样的-嗨,James,请参见上面修改的代码。当我运行此代码时,我真的会暂停,而不会在代码中取得进展。connector类中的读写方法现在只调用pop和push并将其推入基类,pop和push实现锁定互斥锁…想法???可能会在会有帮助的。