4

g++4.7を使用してC++11シードライブラリを使用しようとしています。最初に質問があります。次のリリースでは、pthreadライブラリを手動でリンクする必要がないのでしょうか。

だから私のプログラムは:

#include <iostream>
#include <vector>
#include <thread>

void f(int i) {
    std::cout<<"Hello world from : "<<i<<std::endl;
}

int main() {
    const int n = 4;
    std::vector<std::thread> t;
    for (int i = 0; i < n; ++i) {
        t.push_back(std::thread(f, i));
    }
    for (int i = 0; i < n; ++i) {
        t[i].join();
    }
    return 0;
}

私は次のようにコンパイルします:

g++-4.7 -Wall -Wextra -Winline -std=c++0x -pthread -O3 helloworld.cpp -o helloworld

そしてそれは戻ります:

Hello world from : Hello world from : Hello world from : 32
2
pure virtual method called

terminate called without an active exception
Erreur de segmentation (core dumped)

問題とその解決方法は何ですか?

アップデート:

現在mutexを使用しています:

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

static std::mutex m;

void f(int i) {
    m.lock();
    std::cout<<"Hello world from : "<<i<<std::endl;
    m.unlock();
}

int main() {
    const int n = 4;
    std::vector<std::thread> t;
    for (int i = 0; i < n; ++i) {
        t.push_back(std::thread(f, i));
    }
    for (int i = 0; i < n; ++i) {
        t[i].join();
    }
    return 0;
}

戻ります:

pure virtual method called
Hello world from : 2
terminate called without an active exception
Abandon (core dumped)

更新2:うーん...デフォルトのGCC(g ++ 4.6)で動作しますが、手動でコンパイルしたバージョンのgcc(g ++ 4.7.1)では失敗します。g ++ 4.7.1をコンパイルするのを忘れたオプションはありましたか?

4

1 に答える 1

0

一般的な編集:

複数のスレッドが同時にcoutを使用しないようにするには、文字のインターリーブが発生するため、次の手順に従います。

1)f()の宣言の前に宣言します。

static std::mutex m;

2)次に、次の間の「cout」ラインを保護します。

m.lock();
std::cout<<"Hello world from : "<<i<<std::endl;
m.unlock();

どうやら、いくつかの不明確な理由から、-lpthreadライブラリへのリンクは必須です。少なくとも私のマシンでは、-lpthreadに対してリンクしないと、コアダンプが発生します。-lpthreadを追加すると、プログラムが適切に機能するようになります。

異なるスレッドからcoutにアクセスするときにロックが使用されていない場合、文字がインターリーブする可能性は次のように表されます。

https://stackoverflow.com/a/6374525/1284631

より正確には: "[注:インターリーブされた文字を避けたい場合は、ユーザーはこれらのオブジェクトとストリームの同時使用を複数のスレッドで同期する必要があります。— end note]"

OTOH、少なくともC ++ 11標準では、競合状態が回避されることが保証されています(この標準のgcc / g ++実装はまだ実験レベルであることに注意してください)。

Microsoftの実装( @SChepurinへのhttp://msdn.microsoft.com/en-us/library/c9ceah3b.aspxクレジットを参照)は標準よりも厳格であることに注意してください(明らかに、文字のインターリーブが回避されることが保証されています)が、これはgcc /g++の実装には当てはまらない場合があります。

これは私がコンパイルするために使用するコマンドラインです(更新されたコードバージョンと元のコードバージョンの両方、すべてが私のPCでうまく機能します):

g++ threadtest.cpp -std=gnu++11 -lpthread -O3

OTOH、-lpthreadがないとコンパイルされますが、コアダンプがあります(Linux64ではgcc4.7.2)。

同じマシンで2つの異なるバージョンのgcc/g++コンパイラを使用しているとのことですが。それらを適切に使用するようにしてください(異なるライブラリバージョンを混在させないでください)。

于 2012-12-26T14:55:28.690 に答える