2016-06-08 78 views
0

我有以下一段代码。我正在使用C++ 11线程编写一个简单的多线程生产者消费者问题。多线程程序在状态等待时挂起

class W 
{ 
public: 
    explicit W(); 
    void p(); 
    void c(); 
private: 
    std::deque<std::uint64_t> q; 
    std::shared_ptr<std::mutex> m; 
    std::shared_ptr<std::condition_variable> cvQEmpty; 
    std::shared_ptr<std::condition_variable> cvQFull; 
    const std::size_t queue_size; 
}; 

W::W() 
: m(std::make_shared<std::mutex>()), 
cvQEmpty(std::make_shared<std::condition_variable>()), 
cvQFull(std::make_shared<std::condition_variable>()), 
queue_size(3) 
{ 
} 

void 
W::p() 
{ 
    while(1)  
    { 
     std::unique_lock<std::mutex> lk(*m.get()); 
     if (q.size() >= queue_size) 
     { 
      cvQFull->wait(lk, [this] { return q.size() < queue_size; }); 
     } 
     q.push_back(q.size()); 
     std::cout << "Pushed " << q[q.size() - 1] << std::endl; 
     lk.unlock(); 
     cvQEmpty->notify_one(); 
    } 
} 

void 
W::c() 
{ 
    while (1) 
    { 
    std::unique_lock<std::mutex> lk(*m.get()); 
    if (q.empty()) 
    { 
     cvQEmpty->wait(lk, [this] { return !q.empty(); }); 
    } 
    while(!q.empty()) 
    { 
     const std::uint64_t val = q[0]; 
     std::cout << "Output : " << val << std::endl; 
     q.pop_back(); 
    } 
    lk.unlock(); 
    cvQFull->notify_one(); 
    } 
} 

void 
foo() 
{ 
    W w; 
    std::thread p(&W::p, w); 
    std::thread c(&W::c, w); 
    c.join(); 
    p.join(); 
} 

两个线程在条件等待时死锁。

你能告诉我我要去哪里吗?该程序编译罚款没有任何警告。

使用的编译器是:g ++ - 5.8

+0

你有任何日志?像推1,推2 ..队列满时挂了吗?因为生产者锁定互斥量并等待队列大小减小,但消费者将等待获取由生产者锁定的互斥锁以便消耗..因此死锁.. –

+0

您不需要任何shared_ptrs,就没有任何可共享的东西。使用普通的'std :: mutex'和'std :: condition_variable'。 –

回答

3

非常简单。您是复制您的w参数为这两个线程,调用复制构造函数。那些线程最终使用两个独立的队列!

解决方案:

  • 让你的队列中的shared_ptr像互斥
  • (更好)包括你的论点为std::ref

(在一个侧面说明,explicit W()给你什么都不是只是语法噪声)