Boost 互斥范围锁

2024-04-23

我正在阅读 drdobbs.com 上的 Boost Mutex 教程,并发现了这段代码:

#include <boost/thread/thread.hpp>
#include <boost/thread/mutex.hpp>
#include <boost/bind.hpp>
#include <iostream>

boost::mutex io_mutex;

void count(int id)
{
  for (int i = 0; i < 10; ++i)
  {
    boost::mutex::scoped_lock
      lock(io_mutex);
    std::cout << id << ": " <<
      i << std::endl;
  }
}

int main(int argc, char* argv[])
{
  boost::thread thrd1(
    boost::bind(&count, 1));
  boost::thread thrd2(
    boost::bind(&count, 2));
  thrd1.join();
  thrd2.join();
  return 0;
}

现在我明白 Mutex 的目的是防止两个线程同时访问同一资源,但我没有看到 io_mutex 和 std::cout 之间的相关性。此代码是否只是锁定范围内的所有内容,直到范围完成为止?


现在我明白 Mutex 的目的是防止两个线程同时访问同一资源,但我没有看到 io_mutex 和 std::cout 之间的相关性。

std::cout is a 全局对象,因此您可以将其视为共享资源。如果您从多个线程同时访问它,则这些访问必须以某种方式同步,以避免数据争用和未定义的行为。

通过考虑以下因素,您可能会更容易注意到并发访问的发生:

std::cout << x

实际上相当于:

::operator << (std::cout, x)

这意味着您正在调用一个在std::cout对象,并且您同时从不同的线程执行此操作。std::cout必须以某种方式受到保护。但这并不是唯一的原因scoped_lock在那里(继续阅读)。

此代码是否只是锁定范围内的所有内容,直到范围完成为止?

是的,它锁了io_mutex直到锁对象本身超出范围(作为典型的 RAII 包装器),这发生在 for 循环的每次迭代结束时。

为什么需要它?好吧,虽然在 C++11 中单独插入cout保证是线程安全的,当多个线程输出某些内容时,后续的单独插入可能会交错。

请记住,每次插入operator <<是一个单独的函数调用,就像您正在做的那样:

std::cout << id;
std::cout << ": ";
std::cout << i;
std::cout << endl;

事实是operator <<返回流对象允许您将上述函数调用链接到单个表达式中(就像您在程序中所做的那样),但您有多个单独的函数调用的事实仍然成立。

现在看看上面的代码片段,更明显的是,这个作用域锁的目的是确保以下形式的每条消息:

<id> ": " <index> <endl>

打印时其部分不会与其他消息的部分交错。

另外,在 C++03 中(其中插入cout are not保证是线程安全的),锁会保护cout对象本身被同时访问。

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

Boost 互斥范围锁 的相关文章

随机推荐

  • 将数据库导入 MATLAB 错误

    我正在尝试将表导入到我的 MATLAB 工作区 但它一直向我抛出错误 Undefined function or method fetch for input arguments of type struct 这是我尝试执行的代码 dyn
  • 递归使用 scp 但排除某些文件夹

    假设有一些具有这些结构的文件夹 bench1 1cpu p 0 image bench1 1cpu p 0 fl 1 bench1 1cpu p 0 fl 1 bench1 1cpu p 0 fl 1 bench1 1cpu p 0 fl
  • 如何使用 PJSIP 为 iOS 客户端应用程序捕获并翻译其他语言的传入音频流?

    我想在基于 VoIP 的 iOS 客户端应用程序中集成语言转换器 该应用程序将根据用户选择将实时传入音频流翻译为其他选定的语言 我正在使用 PjSip 开源库来支持 VoIP 呼叫 对于语言翻译 我想使用语音到文本和文本到语音开源库 现在我
  • Windows 上的 PHP mail():没有错误,电子邮件未发送

    我目前正在尝试调试一个基于 Elgg 的网站 我没有开发它 我想直接从本地开发计算机 WinXP 发送电子邮件 我正在使用 Apache 2 2 11 和 PHP 5 3 0 运行 WAMP 经过一番搜索后 我遇到的最简单的解决方案是使用假
  • 分阶段加载 spring 上下文

    这是人们会问的奇怪问题之一 为什么 所以我将从我为什么要这样做开始 然后讨论这个问题 我想更好地控制 spring 上下文的加载方式 例如 我不想同时加载域和web api 这将使资源在其依赖项准备好之前可用 也可能我需要检查某些东西的状态
  • 禁用对特定主机的警报,同时对所有其他主机发出警报

    我有数百台主机向普罗米修斯服务器报告 我的每个主机有很多出口商 我希望能够列出我不希望收到警报的主机列表 我仍然需要对这些主机进行普罗米修斯监控 我尝试过匹配没有接收器的路线 这不起作用 我究竟做错了什么 或者说 我应该怎么做 我的路线规则
  • 为什么 pgAdmin 4 这么慢?

    postgreSQL 的 pgAdmin 4 GUI 非常慢 即使扩展服务器树或数据库树也需要花费太多时间 它们各自花费了近 30 秒的时间来展开 创建新数据库或表时它也会挂起 即使加载后 创建和保存新数据库也需要一分多钟的时间 几乎每次我
  • 回形针未保存,没有错误

    我被绊倒了 浏览了文档 教程等 但不确定我做错了什么 项目中的另一个模型是为 Paperclip 设置的 并且在测试时可以正常工作 它将附件文件信息保存和检索到数据库中 并将文件放入 public system 内的子文件夹中 我基本上将相
  • jQuery 剪贴板复制

    我需要剪贴板复制功能 即使我正在寻求帮助http plugins jquery com project copy http plugins jquery com project copy链接 但无法正常工作 li li
  • Spark:相当于数据帧中的 zipwithindex

    假设我有以下数据框 dummy data a 1 b 25 c 3 d 8 e 1 df sc parallelize dummy data toDF letter number 我想创建以下数据框 a 0 b 2 c 1 d 3 e 0
  • 从坐标中提取地址分量

    我正在尝试使用 R 进行反向地理编码 我首先使用了 ggmap 但无法让它与我的 API 密钥一起使用 现在我正在用 googleway 尝试 newframe c Front lat Front long Front lat Front
  • 共享苹果付费开发者帐户的选项?

    问题 这里正确的程序是什么 Do both the developer and account holder need paid Apple Developer accounts 正如在下面的上下文中所说 我的客户已经有一个 我还需要一个付
  • Kotlin 中 ArrayList() 和 mutableListOf() 之间的区别

    private val repositories mutableListOf
  • 在 ResourceDictionary 文件中使用 viewbox

    我有 ResourceFile1 xaml 文件 其内容
  • 在控制器中使用 Angular 的 $watch 是反模式吗?

    在我永无休止地追求以 正确的 角度方式做事的过程中 我阅读了很多有关如何让控制器观察角度服务中保存的模型变化的文章 一些网站 http www benlesh com 2013 08 angularjs watch digest and a
  • 如何在单页应用程序中实现 gmail 撰写窗口概念?

    我正在开发一个项目 用户可以更轻松地快速添加交易 我非常有兴趣做一些类似于 gmail 撰写弹出窗口在单页上所做的事情 我不知道如何实现这样的事情 请给我指导如何做这些事情 我有兴趣使用 AngularJS 构建它 P S 抱歉问了一个宽泛
  • 包 oracle.jdbc.driver 不存在

    以下代码出错 发生错误 1 import java sql public class DBConnect public static void main String a throws SQLException package oracle
  • 如何使用脚本。在 JADE 模板中

    我使用 JADE 模板使用 Express 框架创建了一个简单的节点应用程序 学习过程中一切都很顺利 直到我开始尝试运行一些客户端 js 但我不知道该怎么做 我需要在 app index js 中做一些事情来告诉节点它们吗 任何帮助将非常感
  • 从相关系数计算中删除异常值

    假设我们有两个数值向量x and y 之间的皮尔逊相关系数x and y是 谁 给的 坐标 x y 我怎样才能自动考虑仅一个子集x and y在计算中 比如90 最大化相关系数 If you really想要做到这一点 删除最大 绝对 残差
  • Boost 互斥范围锁

    我正在阅读 drdobbs com 上的 Boost Mutex 教程 并发现了这段代码 include