ezz*_*rem 0 c++ multithreading boost-thread boost-mutex
我正在玩boost库和C++.我想创建一个包含生产者,conumer和堆栈的多线程程序.procuder填充堆栈,消费者从堆栈中删除items(int).一切正常(pop,push,mutex)但是当我把pop/push winthin称为线程时,我没有任何效果
我做了这个简单的代码:
#include "stdafx.h"
#include <stack>
#include <iostream>
#include <algorithm>
#include <boost/shared_ptr.hpp>
#include <boost/thread.hpp>
#include <boost/date_time.hpp>
#include <boost/signals2/mutex.hpp>
#include <ctime>
using namespace std;
/ *
* this class reprents a stack which is proteced by mutex
* Pop and push are executed by one thread each time.
*/
class ProtectedStack{
private :
stack<int> m_Stack;
boost::signals2::mutex m;
public :
ProtectedStack(){
}
ProtectedStack(const ProtectedStack & p){
}
void push(int x){
m.lock();
m_Stack.push(x);
m.unlock();
}
void pop(){
m.lock();
//return m_Stack.top();
if(!m_Stack.empty())
m_Stack.pop();
m.unlock();
}
int size(){
return m_Stack.size();
}
bool isEmpty(){
return m_Stack.empty();
}
int top(){
return m_Stack.top();
}
};
/*
*The producer is the class that fills the stack. It encapsulate the thread object
*/
class Producer{
public:
Producer(int number ){
//create thread here but don't start here
m_Number=number;
}
void fillStack (ProtectedStack& s ) {
int object = 3; //random value
s.push(object);
//cout<<"push object\n";
}
void produce (ProtectedStack & s){
//call fill within a thread
m_Thread = boost::thread(&Producer::fillStack,this, s);
}
private :
int m_Number;
boost::thread m_Thread;
};
/* The consumer will consume the products produced by the producer */
class Consumer {
private :
int m_Number;
boost::thread m_Thread;
public:
Consumer(int n){
m_Number = n;
}
void remove(ProtectedStack &s ) {
if(s.isEmpty()){ // if the stack is empty sleep and wait for the producer to fill the stack
//cout<<"stack is empty\n";
boost::posix_time::seconds workTime(1);
boost::this_thread::sleep(workTime);
}
else{
s.pop(); //pop it
//cout<<"pop object\n";
}
}
void consume (ProtectedStack & s){
//call remove within a thread
m_Thread = boost::thread(&Consumer::remove, this, s);
}
};
int main(int argc, char* argv[])
{
ProtectedStack s;
Producer p(0);
p.produce(s);
Producer p2(1);
p2.produce(s);
cout<<"size after production "<<s.size()<<endl;
Consumer c(0);
c.consume(s);
Consumer c2(1);
c2.consume(s);
cout<<"size after consumption "<<s.size()<<endl;
getchar();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我在VC++ 2010/win7中运行后得到:0 0
你能帮我理解为什么当我从主要调用fillStack函数时我得到了一个效果但是当我从一个线程调用它时没有任何反应?谢谢
您的示例代码遇到了其他人指出的几个同步问题:
我建议在生产者和消费者之间使用条件变量进行同步.请看一下这里的生产者/消费者示例:http://en.cppreference.com/w/cpp/thread/condition_variable 这是标准库中从C++ 11开始的一个相当新的功能,从VS2012开始支持.在VS2012之前,您需要提升或使用Win32调用.
使用条件变量来解决生产者/消费者问题是很好的,因为它几乎强制使用互斥锁来锁定共享数据,并且它提供了一种信令机制,让消费者知道某些东西已经准备好被消费,所以他们没有那么旋转(这总是在消费者的响应性和轮询队列的CPU使用率之间进行权衡).它也是原子本身,它可以防止线程丢失信号的可能性,这里有一些消耗,如下所述:https://en.wikipedia.org/wiki/Sleeping_barber_problem
简要介绍一下条件变量如何解决这个问题......
这会对您的代码产生以下影响:
我觉得线程对你来说是一个新的东西,所以我只能提供建议,看看其他人如何解决同步问题,因为很难解决这个问题.对具有多个线程和共享数据的环境中发生的事情的困惑通常会导致诸如死锁之类的问题.