繁体   English   中英

提升Mutex Scoped Lock

[英]Boost Mutex Scoped Lock

我正在阅读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是一个全局对象 ,因此您可以将其视为共享资源。 如果从多个线程同时访问它,则必须以某种方式同步这些访问,以避免数据争用和未定义的行为。

通过考虑以下情况,您可能会更容易注意到并发访问:

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并不保证是线程安全的),锁将保护cout对象本身不被同时访问。

互斥锁与程序中的任何其他内容(条件变量除外)无关,至少在更高级别。 互斥锁有两个有效之处:它控制程序流,并防止多个线程同时执行相同的代码块。 它还确保了内存同步。 这里的重要问题是互斥体与资源无关,并且不会阻止两个线程同时访问同一资源。 互斥锁定义代码的关键部分,一次只能由一个线程输入。 如果在由相同互斥锁控制的关键部分中完成对特定资源的所有使用,则该资源将受到互斥锁的有效保护。 但是这种关系是由编码人员确定的,确保所有使用确实发生在关键部分。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM