关闭GCC中的COW

Turning off COW in GCC

本文关键字:COW 中的 GCC 关闭      更新时间:2023-10-16

我早就知道GCC对std::string使用COW(写时复制),这使得在多线程程序中无法使用std::string。但据我所知,C++11禁止实现使用COW,因为线程现在是由标准定义的,而且语义已经过时了,无论如何都需要COW。

现在,GCC 4.6实现了大量的C++11标准。然而,似乎的实现仍然使用COW语义。在我编写的一个多线程应用程序中,随机出现的神秘seg错误引起了我的注意。我已经通过以下测试代码确认了这实际上是一个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语义吗?或者,在GCC修复此问题之前,我现在需要使用std::vector<char>吗?

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

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

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