关闭GCC中的COW

时间:2012-09-14 19:12:02

标签: c++ string gcc c++11 thread-safety

我早就知道GCC对std::string使用COW(Copy-On-Write),因此无法在多线程程序中使用std::string。但据我所知,C ++ 11禁止使用COW实现,因为线程现在由标准定义,并且移动语义几乎已经过时了对COW的需求。

现在,GCC 4.6实现了大量的C ++ 11标准。但似乎实现仍然使用COW语义。在我写的多线程应用程序中,随机发生的神秘seg-fault引起了我的注意。事实上,我通过以下测试代码证实了这是一个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程序。这是一个link to ideone确认我在说什么,(至少对于GCC 4.5.1这个意思何时使用)

我不记得原因,但出于某种原因,我认为std=c++0x标志会消除COW语义,但事实并非如此。上面代码中的断言是成功的,即使使用--std = c ++ 0x标志。所以基本上,从GCC 4.6开始,std::string在多线程中仍然无法使用应用

有没有办法禁用COW语义?或者我现在需要使用std::vector<char>,直到GCC解决了这个问题?

1 个答案:

答案 0 :(得分:7)

如果要在线程边界上传递字符串,请执行显式复制,以强制它为独立字符串,然后将其传递:

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

在所有交叉线程的地方必须这样做很烦人,但在我看来,它比vector<char>更容易。