16

GCC が に COW (Copy-On-Write)std::stringを使用std::stringしているため、マルチスレッド プログラムでは使用できないことは以前から知っていました。しかし、私が知る限り、C++11 では実装で COW を使用することは禁止されています。これは、スレッドが標準で定義されているためであり、ムーブ セマンティクスによって COW の必要性がほとんど時代遅れになっているためです。

現在、GCC 4.6 は多くの C++11 標準を実装しています。それでも、実装はまだCOW セマンティクスを使用しているようです。これは、私が作成したマルチスレッド アプリケーションでランダムに発生する不可解なセグメンテーション フォールトによって注意を喚起されました。実際、これが COW の問題であることを次のテスト コードで確認しました。

#include <iostream>
#include <string>
#include <cassert>
#include <thread>
using namespace std;

int main()
{
    std::string orig = "abc";
    std::string copy = orig;
    std::cout << (void*) orig.data() << ", " << (void*) copy.data() << endl;
    assert(orig.data() == copy.data());
}


編集:ここにヘッダーが含まれていることに注意してください<thread>。これは、これが C++11 プログラムであることを証明しています。そして、ここに私が言っていることを確認するideoneへのリンクがあります(少なくともideoneが使用するGCC 4.5.1の場合)

理由は覚えていませんが、何らかの理由でstd=c++0xフラグが COW セマンティクスを排除するという印象を受けましたが、そうではありません。--std=c++0x フラグを使用しても、上記のコードのアサーションは成功します。 基本的に、GCC 4.6 の時点でstd::stringは、マルチスレッド アプリケーションではまだ使用できません。

COW セマンティクスを無効にする方法はありますか? std::vector<char>それとも、GCC がこれを修正するまで、今のところ使用する必要がありますか?

4

1 に答える 1

7

If you're going to pass a string across a thread boundary, do an explicit copy, in order to force it to be an independent string, then pass that across:

std::string a="bob";
std::string b(a.data(), a.length());

It's annoying to have to do this at all spots where things cross threads, but in my opinion it's easier than vector<char>.

于 2012-09-14T19:20:00.343 に答える