多线程程序中的 std::string

2024-04-18

鉴于:

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

2) C++03 标准将其留给实现来决定是否std::string应该在其复制构造函数中使用 Copy-on-Write 语义

3)写时复制语义通常会导致多线程程序中不可预测的行为

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

您根本无法在多线程程序中安全且可移植地使用 std::string

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

现实世界的例子:

在我的公司,我们有一个多线程应用程序,它已经过彻底的单元测试并通过 Valgrind 运行了无数次。该应用程序运行了几个月,没有出现任何问题。有一天,我在另一个版本的 gcc 上重新编译该应用程序,突然间我总是遇到随机的段错误。 Valgrind 现在在 std::string 复制构造函数中报告 libstdc++ 深处的无效内存访问。

那么解决办法是什么呢?嗯,当然,我可以 typedefstd::vector<char>作为一个字符串类 - 但实际上,这很糟糕。我还可以等待 C++0x,我祈祷它会要求实现者放弃 COW。或者,(颤抖),我可以使用自定义字符串类。我个人总是抱怨开发人员在现有的库可以很好地工作时实现自己的类,但老实说,我需要一个字符串类,我可以确定它没有使用 COW 语义;而 std::string 根本不能保证这一点。

我说得对吗std::string根本无法可靠使用at all在可移植的多线程程序中?什么是好的解决方法?


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

标准中也没有任何内容可以保证vector可以按照你说的方式使用。提供带有线程扩展的 C++ 实现是合法的,例如,在初始化向量的线程之外使用向量会导致未定义的行为。当您启动第二个线程时,您就不再使用标准 C++,并且您必须向编译器供应商询问什么是安全的,什么是不安全的。

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

您可以通过使用单个互斥体来确保安全,在进行任何字符串突变以及对作为副本结果的字符串的任何读取时使用该互斥体。但是您可能会在该互斥体上遇到严重的争用。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

多线程程序中的 std::string 的相关文章

随机推荐

  • numpy 赋值不起作用

    假设我有以下内容numpy array In x Out array 1 2 3 4 5 5 2 4 1 5 6 7 2 5 1 dtype int16 In y Out array 3 4 4 1 dtype int16 我想替换一个子数
  • scipy.stats.maxwell中的loc和scale参数是什么?

    The maxwell boltzmann distribution is given by from MathWorld A Wolfram Web Resource wolfram com http mathworld wolfram
  • 理解Sinon.js的yield()、yields()和callsArg()

    有什么区别 stub yield arg1 arg2 spy yields arg1 arg2 stub callsArg index in the Sinon js http sinonjs org docs stubs存根库 stub
  • Android 如何从已知的 URI 获取单首歌曲的 ID 信息

    我知道单曲的 URI 如何获取歌曲的信息 主打歌等 抱歉 我能找到的所有帖子都提供了一种索引整个库的方法 而不是如何获取单个已知 URI 歌曲的信息 这就是我用来获取 URI 的方法 audioID 存储在 SharedPrefs 中 谢谢
  • 通过 Activator.CreateInstance 创建可为 null 的对象返回 null

    我正在创建一个将小脚本转换为 dll 的系统 当我尝试采用可为空值类并将其设为参数的默认值时 我遇到了问题 问题是我需要在编译器中创建用户选择的可为空的实例并将其设置为常量 不幸的是 每当我使用Activator CreateInstanc
  • 对在欧盟地区运行的 Heroku 应用程序强制使用 SSL

    我正在努力为 Heroku 欧盟地区 上运行的 Rails 应用程序强制实施 SSL 连接 我已成功将证书 包括 Heroku SSL 附加组件 添加到自定义域 如果我明确声明 https com 则效果完美 但我想将所有 http 请求重
  • 您能解释一下 md5 和 modulo 的这些令人不安的异常情况吗?

    好吧 标题确实很主观 但这正是我的问题所在 背景是我想将静态 Web 内容的点击均匀地分布在定义数量的缓存服务器上 此外 向客户端的交付应该会加快 因为多个域正在使用中并且请求不会相互阻塞 我也不需要经典的负载均衡器 而是立即在我的 htm
  • 添加渐变背景色和描边 - CSS

    我已将背景渐变添加到其中一个 css 类中 但它从笔画中获取颜色 有没有办法使边框渐变 flex wrapper display flex flex flow row nowrap single chart margin left 160p
  • 调试变量不适用于 gulp sourcemaps + uglify

    我有以下用于捆绑 javascript 的 gulp 任务 gulp task js function return gulp src paths js pipe sourcemaps init pipe uglify pipe conca
  • 在 MATLAB 中调整 3D 矩阵(图像)的大小

    我有一个 3D 矩阵 MxNxK 想将其大小调整为 M xN xK 就像 matlab 中的 imresize 一样 我正在使用图像金字塔 但其结果不是很准确 需要一个更好的 有什么解决办法吗 你可以使用interp3 因为您想要插入 3D
  • 从 Dataflow 写入 BigQuery - 作业完成时不会删除 JSON 文件

    我们的 Dataflow 作业之一将其输出写入 BigQuery 我对其幕后实现方式的理解是 Dataflow 实际上将 JSON 格式的结果 分片 写入 GCS 然后启动 BigQuery 加载作业以导入该数据 但是 我们注意到 无论作业
  • CSS 中的鼠标按下选择器是什么?

    我注意到按钮和其他元素具有默认样式 并按 3 个步骤运行 普通视图 悬停 焦点视图和鼠标按下 单击视图 在 CSS 中我可以更改普通视图和悬停视图的样式 如下所示 button background 333 color FFF button
  • ngResource 将 POST 参数附加到 url

    我有一个看起来像这样的角度服务 我在这里发出 POST 请求 factory Apples function resource HOST return resource HOST apples create method POST para
  • 使用 XPath 排序 - 不是 XSL

    XPath DOM 编程中有什么方法可以使用System Xml to run selectNodes XPATH 带有排序参数 例如 对于以下 XML 程序按照与文档相同的顺序 降序 写入值 有没有办法使用 XPath 来按升序获取值 笔
  • 是否可以使用计时器为 JButton 创建淡入效果?

    我想在我的程序按钮上添加一些效果 当我按下button the button应该淡入 Using a timer改变的值Opaque in new Color 是一种方式 但是可以应用于JButton还有 因为JButton有边界 所以我想
  • 分配后列表被意外清除[重复]

    这个问题在这里已经有答案了 class ListHolder public List
  • 应用程序中所有国家/地区的城市和邮政编码

    有没有一种方法可以将所有国家 州 城市的邮政编码存储在一个数据库中 我一直在到处寻找 我发现地名网 http www geonames org 我猜其中包含了所有内容 但无法直接获取该数据 我正在使用导轨 如果有任何助手或插件就太好了 如果
  • 更改 iOS 中的应用程序语言设置而不是整个设备

    我希望在我的应用程序中可以选择更改我的应用程序语言 只是应用程序语言而不是整个系统 请给我一些提示好吗 提前致谢 我知道本地化 您可以使用从 Xcode 设置的自定义构建标志来完成此操作 这样您就可以在本地化下运行应用程序 而无需更改设备的
  • 当我单击数据表中的下一页时,我的 jquery 选择器不再工作

    我在用着数据表 http www datatables net jquery 插件在页面上显示我的数据 当有人单击一行时 我有这个选择器 myTable tr class tableHeader click function alert c
  • 多线程程序中的 std::string

    鉴于 1 C 03标准没有以任何方式解决线程的存在 2 C 03 标准将其留给实现来决定是否std string应该在其复制构造函数中使用 Copy on Write 语义 3 写时复制语义通常会导致多线程程序中不可预测的行为 我得出以下看