C++ 提升互斥范围锁

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/16882809/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 20:43:39  来源:igfitidea点击:

Boost Mutex Scoped Lock

c++multithreadingboostmutexscoped-lock

提问by Joe Wilcoxson

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

我正在阅读 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;
}

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?

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

回答by Andy Prowl

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.

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

std::coutis 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.

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

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::coutobject, and you are doing so from different threads at the same time. std::coutmust be protected somehow. But that's not the only reason why the scoped_lockis there (keep reading).

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

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

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

Yes, it locks io_mutexuntil 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.

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

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

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

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

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

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.

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

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 coutare notguaranteed to be thread-safe) , the lock will protect the coutobject itself from being accessed concurrently.

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

回答by James Kanze

A mutex has nothing to do with anything else in the program (except a conditional variable), at least at a higher level. A mutex has two effeccts: it controls program flow, and prevents multiple threads from executing the same block of code simultaneously. It also ensures memory synchronization. The important issue here, is that mutexes aren't associated with resources, and don't prevent two threads from accessing the same resource at the same time. A mutex defines a critical section of code, which can only be entered by one thread at a time. If all of the use of a particular resource is done in critical sections controled by the same mutex, then the resource is effectively protected by the mutex. But the relationship is established by the coder, by ensuring that all use does take place in the critical sections.

互斥体与程序中的其他任何东西(条件变量除外)无关,至少在更高级别上如此。互斥锁有两个作用:控制程序流,防止多个线程同时执行同一块代码。它还确保内存同步。这里的重要问题是互斥体不与资源关联,并且不会阻止两个线程同时访问同一资源。互斥锁定义了代码的临界区,一次只能由一个线程进入。如果特定资源的所有使用都在由同一互斥锁控制的临界区中完成,那么该资源就受到互斥锁的有效保护。但是这种关系是由编码人员通过确保所有使用都发生在临界区中来建立的。