升压互斥锁作用域 [英] Boost Mutex Scoped Lock

查看:141
本文介绍了升压互斥锁作用域的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在读通过drdobbs.com升压互斥的教程,并发现了这片code的:

 的#include<升压/线程/ thread.hpp>
#包括LT&;升压/线程/ mutex.hpp>
#包括LT&;升压/ bind.hpp>
#包括LT&;&iostream的GT;提高::互斥io_mutex;无效计数(INT ID)
{
  对(INT I = 0; I&小于10 ++ⅰ)
  {
    提高::互斥:: scoped_lock中
      锁定(io_mutex);
    性病::法院LT&;< ID<< :&所述;&下;
      I<<的std :: ENDL;
  }
}INT主(INT ARGC,CHAR *的argv [])
{
  提高::线程锁而(
    提高::绑定(安培;算,1));
  提高::线程对于thrd2(
    提高::绑定(安培;算,2));
  thrd1.join();
  thrd2.join();
  返回0;
}

现在我明白了一个互斥的一点是prevent从在同一时间访问同一资源的两个线程,但我没有看到io_mutex和std ::法院之间的关系。难道直到范围完成了这个code只是范围内锁定的一切吗?


解决方案

  

现在我明白了一个互斥的一点是prevent从在同一时间访问同一资源的两个线程,但我没有看到io_mutex和std ::法院之间的关系。


的std :: COUT 全局对象,所以你可以看到,作为一个共享的资源。如果您从多个线程同时访问,这些访问必须以某种方式同步,以避免数据种族和未定义的行为。

也许这将是您更容易发现通过考虑发生时的并发访问:

 的std ::法院LT&;< X

其实就相当于:

  ::运算<< (STD ::法院,X)

这意味着你要拨打的的std :: COUT 对象操作的功能,并正在从不同的线程在同一时间这样做。 的std :: COUT 必须以某种方式保护。但是,这并不是唯一的原因的scoped_lock 有(​​请继续阅读)。


  

请问直到范围完成了这个code只是范围内锁定的一切吗?


是的,它锁定 io_mutex ,直到锁定对象本身超出范围(即典型的RAII包装),这发生在你对循环的每个迭代结束

为什么需要它?好吧,虽然在C ++ 11个人到插入 COUT 保证是线程安全的,随后,独立插入可当多个线程输出交错的东西。

请记住,每次插入到运营商的LT;< 是一个单独的函数调用,因为如果你是这样做的:

 的std ::法院LT&;< ID;
性病::法院LT&;< :;
性病::法院LT&;<一世;
性病::法院LT&;< ENDL;

事实上,运营商的LT;< 返回流对象允许您链在一个前pression上面的函数调用(如你在做了你的程序),但你有几个独立的功能实际上调用仍然有效。

现在看着上面的片段,更明显的是,这样做的目的范围锁,以确保表单的每个消息:

 <&ID GT; :<索引> <&ENDL GT;

获取打印没有它的部分是交错与来自其他消息部分。

此外,在C ++ 03(其中插入到 COUT 是的的保证是线程安全的),锁将保护 COUT 对象本身被并发访问。

I was reading through a Boost Mutex tutorial on drdobbs.com, and found this piece of code:

#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;
}

Now I understand the point of a Mutex is to prevent two threads from accessing the same resource at the same time, but I don't see the correlation between io_mutex and std::cout. Does this code just lock everything within the scope until the scope is finished?

解决方案

Now I understand the point of a Mutex is to prevent two threads from accessing the same resource at the same time, but I don't see the correlation between io_mutex and std::cout.

std::cout is a global object, so you can see that as a shared resource. If you access it concurrently from several threads, those accesses must be synchronized somehow, to avoid data races and undefined behavior.

Perhaps it will be easier for you to notice that concurrent access occurs by considering that:

std::cout << x

Is actually equivalent to:

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

Which means you are calling a function that operates on the std::cout object, and you are doing so from different threads at the same time. std::cout must be protected somehow. But that's not the only reason why the scoped_lock is there (keep reading).

Does this code just lock everything within the scope until the scope is finished?

Yes, it locks io_mutex until the lock object itself goes out of scope (being a typical RAII wrapper), which happens at the end of each iteration of your for loop.

Why is it needed? Well, although in C++11 individual insertions into cout are guaranteed to be thread-safe, subsequent, separate insertions may be interleaved when several threads are outputting something.

Keep in mind that each insertion through operator << is a separate function call, as if you were doing:

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

The fact that operator << returns the stream object allows you to chain the above function calls in a single expression (as you have done in your program), but the fact that you are having several separate function calls still holds.

Now looking at the above snippet, it is more evident that the purpose of this scoped lock is to make sure that each message of the form:

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

Gets printed without its parts being interleaved with parts from other messages.

Also, in C++03 (where insertions into cout are not guaranteed to be thread-safe) , the lock will protect the cout object itself from being accessed concurrently.

这篇关于升压互斥锁作用域的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆