代码之家  ›  专栏  ›  技术社区  ›  Charles Salvia

多线程程序中的std::string

  •  34
  • Charles Salvia  · 技术社区  · 16 年前

    鉴于:

    1) C++03标准没有以任何方式解决线程的存在问题

    2) C++03标准让实现来决定是否 std::string

    我得出以下看似有争议的结论:

    显然,没有STL数据结构是线程安全的。但至少,以std::vector为例,您可以简单地使用互斥来保护对该向量的访问。对于使用COW的std::string实现,如果不在供应商实现的深层编辑引用计数语义,您甚至无法可靠地做到这一点。

    现实世界的例子:

    那么解决方案是什么呢?好吧,当然可以 std::vector<char>

    我说的对吗 字符串 根本无法可靠地使用 完全 在可移植的多线程程序中?什么是好的解决方法?

    8 回复  |  直到 11 年前
        1
  •  12
  •   YeahStu    16 年前

    在多线程程序中,您无法安全且可移植地执行任何操作。不存在可移植的多线程C++程序,正是因为线程将C++关于操作顺序的所有内容以及修改任何变量的结果都抛到了窗外。

    vector

    如果您的供应商提供了一个线程扩展,并且还提供了一个带有COW的std::string(因此)无法使其成为线程安全的,那么我认为目前您的论点是与您的供应商或线程扩展有关,而不是与C++标准有关。例如,POSIX应该在使用pthreads的程序中禁用COW字符串。

    您可以通过使用一个互斥锁(在执行任何字符串变异时使用该互斥锁)和任何复制结果的字符串读取来确保安全。但是你可能会在互斥上遇到严重的争论。

        2
  •  8
  •   sellibitze    16 年前

    你是对的。这将在C++0x中修复。现在,您必须依赖于实现的文档。例如,最近的libstdc++版本(GCC)允许您使用字符串对象 犹如

        3
  •  6
  •   Arkaitz Jimenez    16 年前

    考虑到该标准对内存模型只字未提,而且完全没有线程意识,我想说,你不能肯定地认为每个实现都是非cow的,所以不,你不能

    除此之外,如果您了解您的工具,大多数实现将使用非cow字符串来允许多线程。

        4
  •  4
  •   Stack Overflow is garbage    16 年前

    更正确的看法是“在多线程环境中无法安全且可移植地使用C++”。也不能保证其他数据结构的行为是合理的。或者运行时不会炸毁你的电脑。标准并不能保证 任何东西 关于线程。

    对于C++中的线程,您必须依赖于实现定义的保证。然后你就可以安全地使用 std::string

    字符串

        5
  •  2
  •   user184968 user184968    16 年前

    您可以使用STLport。它提供非COW字符串。它在不同的平台上有相同的行为。

    这个 article 基于STLport字符串、ROPE和GNU libstdc的写参数算法++ 实现。

    在我工作的一家公司,我有一些在HP-UX 11.31上运行使用STLport和不使用STLport构建的相同服务器应用程序的经验。该应用程序使用GCC4.3.1编译,优化级别为O2。因此,当我运行使用STLport构建的程序时,它处理请求的速度比不使用STLport构建的相同程序(使用gcc自己的STL库)快25%。

    pthread_mutex_unlock() (2.5%)与使用STLport的版本(1%)相比。及 pthread_mutex_unlock() 在没有STLport的版本中,它本身是从std::string函数之一调用的。

    但是,在评测之后,我以这种方式更改了最常调用函数中字符串的赋值:

    string_var = string_var.c_str(); // added .c_str()
    

    没有STLport的版本的性能有了显著的提高。

        6
  •  1
  •   Pavel Radzivilovsky    16 年前

    在MSVC中,std::string不再是指向容器的引用计数共享指针。它们选择在每个复制构造函数和赋值运算符中按值分配整个内容,以避免多线程问题。

        7
  •  0
  •   jdehaan    16 年前

    我规范字符串访问:

    • std::string 非公开成员
    • 返回 const std::string&

        8
  •  0
  •   Bill    14 年前

    如果要禁用COW语义,可以强制字符串进行复制:

    // instead of:
    string newString = oldString;
    
    // do this:
    string newString = oldString.c_str();
    

    string newString(oldString.begin(), oldString.end());