16

我早就知道 GCC 使用 COW (Copy-On-Write) for 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

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

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

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

于 2012-09-14T19:20:00.343 回答