2012-08-30 45 views
0

我正在寫一個消費者/生產者類與一個簡單的信號量實現爲c + + 11。但是,以下代碼無法編譯。如果我刪除producer_consumer類並使producerconsumer全局函數,並將線程創建部分(std::thread t1(consumer), t2(consumer); t1.join(); t2.join();)移動到main函數,它編譯但實現仍然不正確,最終導致分段錯誤。我該如何糾正代碼?謝謝。如何更正下面的生產者消費者代碼的c + + 11

#include <iostream> 
#include <thread> 
#include <mutex> 

class semaphore { 
private: 
    std::mutex m; 
    std::condition_variable cond; 
    unsigned long n; 
public: 
    semaphore(int i) : n(i) {} 

    void up() { 
     std::unique_lock <std::mutex> lock (m); 
     ++n; 
     cond.notify_one(); 
    } 

    void down() { 
     std::unique_lock <std::mutex> lock (m); 
     while(!n) cond.wait(lock); 
     --n; 
    } 
}; 
class producer_consumer{ 
private: 
    semaphore full, empty; 
    int i = 0; 
    std::thread t1, t2; 
public: 
    producer_consumer(int n): full(0), empty(n), i(0){} 
    void run(){ 
     t1 = std::thread(&producer_consumer::producer, *this); 
     t2 = std::thread(&producer_consumer::consumer, *this); 
    } 
    void stop(){ 
     t1.join(); 
     t2.join(); 
    } 
    void producer(){ 
     while (true){ 
      empty.down(); 
      i ++; 
      std::cout << "[p]" << i << std::endl; 
      full.up(); 
     } 
    } 
    void consumer(){ 
     while (true){ 
      full.down(); 
      i --; 
      std::cout << "[c]" << i << std::endl; 
      empty.up(); 
     } 
    } 
}; 

int main(){ 
    producer_consumer pc(5); 
    pc.run(); 
    pc.stop(); 
    return 0; 
} 

我用鐺++編譯文件:

clang++ -std=c++0x -stdlib=libc++ pc.cpp ; ./a.out 

錯誤消息:

In file included from file_name.cpp:1: 
In file included from /usr/bin/../lib/c++/v1/iostream:38: 
In file included from /usr/bin/../lib/c++/v1/ios:216: 
In file included from /usr/bin/../lib/c++/v1/__locale:15: 
In file included from /usr/bin/../lib/c++/v1/string:434: 
In file included from /usr/bin/../lib/c++/v1/algorithm:591: 
/usr/bin/../lib/c++/v1/type_traits:1423:12: error: call to implicitly-deleted 
     copy constructor of 'typename decay<producer_consumer &>::type' 
     (aka 'producer_consumer') 
    return _VSTD::forward<_Tp>(__t); 
      ^~~~~~~~~~~~~~~~~~~~~~~~ 

更新:@DanqiWang通過改變*thisthis解決編制問題。 目前看來,信號燈無法正常工作,最後會崩潰的程序:

./a.out 
[p]1 
[p]2 
[p]3 
[p]4 
[p]5 
.... 
[p]2 
[p]3 
[p]4 
1 
[c]3 
[p[]c3] 
3 
[[c]3 
p][2c 
][p]3 
[p]4 
4 
[c]3 
[c]2 
Segmentation fault: 11 
+0

如果存在編譯器錯誤,請顯示錯誤消息;如果出現意外的行爲,請描述它。這可能有助於他人理解和解決您的問題。 –

+0

@DanqiWang:發佈錯誤消息 –

+1

將'* this'改爲'this'應該編譯:'t1 = std :: thread(&producer_consumer :: producer,this); t2 = std :: thread(&producer_consumer :: consumer,this);' –

回答

2

我對你的代碼如下建議:

  • 雖然iostream成爲線程安全的C++ 11,它應該被鎖定以避免輸出錯亂。
  • 使用std::atomic而不是裸體int
  • 如果存在段故障,請轉儲內核,使用gdb進行調試,或者在此處發佈堆棧跟蹤。

希望這些幫助。

+0

非常感謝!這是正確的答案。 –

+0

因此,通過點擊左下方的勾號(複選標記),接受答案。 –

+0

全局流對象具有很強的保證。什麼'std :: printf'具有其他那些呢? –