【发布时间】:2009-11-02 12:55:14
【问题描述】:
鉴于:
1) C++03 标准没有以任何方式解决线程的存在
2) C++03 标准让实现来决定 std::string 是否应该在其复制构造函数中使用 Copy-on-Write 语义
3) Copy-on-Write 语义通常会导致多线程程序中出现不可预知的行为
我得出以下看似有争议的结论:
您根本无法在多线程程序中安全且可移植地使用 std::string
显然,没有 STL 数据结构是线程安全的。但至少,以 std::vector 为例,您可以简单地使用互斥锁来保护对向量的访问。使用使用 COW 的 std::string 实现,如果不在供应商实现的深处编辑引用计数语义,您甚至无法可靠地做到这一点。
现实世界的例子:
在我的公司,我们有一个多线程应用程序,它已经过彻底的单元测试并无数次地通过 Valgrind 运行。该应用程序运行了几个月,没有任何问题。有一天,我在另一个版本的 gcc 上重新编译了应用程序,突然间我总是得到随机的段错误。 Valgrind 现在在 std::string 复制构造函数中报告 libstdc++ 深处的无效内存访问。
那么解决方法是什么?好吧,当然,我可以 typedef std::vector<char> 作为字符串类 - 但实际上,这很糟糕。我也可以等待 C++0x,我祈祷这将要求实现者放弃 COW。或者,(颤抖),我可以使用自定义字符串类。我个人总是反对那些实现自己的类的开发人员,但老实说,我需要一个字符串类,我可以肯定它没有使用 COW 语义;而 std::string 根本不保证这一点。
std::string 根本无法在可移植的多线程程序中完全可靠地使用,这对吗?什么是好的解决方法?
【问题讨论】:
-
哇,我什至不知道 COW 字符串实现还在外面。
-
如果您的 STL 实现使用非线程安全的 COW,您应该将其替换为更好的。这对我来说似乎是一个错误。
-
@sbi,不仅在外面,而且很常见。 GCC 4.3.2(从 2008 年 8 月开始)使用 COW。
-
std::vector<char>有什么不好?