关闭GCC中的COW

Cha*_*l72 16 c++ string gcc thread-safety c++11

我早就知道GCC使用COW(Copy-On-Write)std::string,因此无法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());
}
Run Code Online (Sandbox Code Playgroud)


编辑:注意<thread>这里包含标题,证明这是一个C++ 11程序.这里有一个连接到ideone确认我在说什么,(至少对于GCC 4.5.1,ideone使用)

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

有没有办法禁用COW语义?或者我std::vector<char>现在需要使用,直到GCC修复此问题?

Mic*_*hne 7

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

std::string a="bob";
std::string b(a.data(), a.length());
Run Code Online (Sandbox Code Playgroud)

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

  • 是的,这是一个明显的解决方法.但是更基本的问题呢:GCC在这种情况下是否遵守标准?OP的代码不应该起作用吗?他说COW是不允许的. (6认同)
  • OP说他传入了`--std = c ++ 0x`- (2认同)