0

私は、c++11の単純なセマフォ実装を使用してコンシューマー/プロデューサークラスを作成しています。ただし、次のコードはコンパイルに失敗します。producer_consumerクラスとmakeproducerおよびグローバル関数を削除し、consumerスレッド作成部分(std::thread t1(consumer), t2(consumer); t1.join(); t2.join();)をmain関数に移動すると、コンパイルされますが、実装はまだ正しくなく、最終的にセグメンテーション違反につながります。コードを修正するにはどうすればよいですか?ありがとう。

#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++を使用してファイルをコンパイルします:

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は、に変更することでコンパイルの問題を解決し*thisましたthis。これで、セマフォが正しく機能しておらず、最終的にプログラムがクラッシュするようです。

./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
4

1 に答える 1

3

私はあなたのコードについて次の提案があります:

  • iostreamC ++ 11ではスレッドセーフになりますが、出力が乱れるのを防ぐためにロックする必要があります。
  • std::atomic裸の代わりに使用してintください。
  • セグメント障害がある場合は、コアをダンプするgdbか、デバッグに使用するか、ここにスタックトレースを投稿します。

これらの助けを願っています。

于 2012-08-30T05:57:27.763 に答える