简体   繁体   English

对于临界区 - 何时使用 std::mutex 与 std::atomic_flag?

[英]For critical sections - when to use std::mutex vs std::atomic_flag?

Here is an implementation of Spinlock class using STL atomic_flag, Taken from https://www.modernescpp.com/index.php/the-atomic-flag .这是使用 STL atomic_flag 的 Spinlock 类的实现,摘自https://www.modernescpp.com/index.php/the-atomic-flag

class Spinlock{
public:
  Spinlock(): flag(ATOMIC_FLAG_INIT) {}

  void lock(){
    while( flag.test_and_set() );
  }

  void unlock(){
    flag.clear();
  }

 private:
   std::atomic_flag flag;
 };

And I can use it for any critical section of the code:我可以将它用于代码的任何关键部分:

 void myfunction() {
     std::lock_guard<Spinlock> guard(_spinLock);
     ...
 }

Revised question:修改后的问题:

For critical sections, seems I now have two choices - std::mutex and std::atomic_flag.对于临界区,似乎我现在有两个选择 - std::mutex 和 std::atomic_flag。 When does it make sense to use one over the other?什么时候使用一个比另一个更有意义?

std::mutex can be used also in conjunction with conditions , which your class cannot directly do. std::mutex也可以与conditions结合使用,而你的类不能直接这样做。 It also works nicely with scoped locks.它也可以很好地与作用域锁配合使用。

Asides from that, your statement除此之外,你的陈述

it is more efficient它更有效率

is not categorically true.不是绝对正确的。 The line线

while( flag.test_and_set() );

is busy waiting , which in some settings is efficient, and in other settings inferior to exponential backoff, for example.例如,忙等待,这在某些设置中是有效的,而在其他设置中不如指数退避。

The question is: what do you want to achieve and what sacrifices are you willing to make for that?问题是:你想达到什么目标,你愿意为此做出什么牺牲?

std::atomic_flag is constantly asking for the lock to get access to the critical section, which keeps the CPU core on which it is running 100% busy. std::atomic_flag不断请求锁以访问临界区,这使运行它的 CPU 内核保持 100% 忙碌。 It won't be a problem if you have enough cores you can operate with, or not many of your threads are operating on the same critical section at the same time.如果您有足够多的内核可以操作,或者没有多少线程同时在同一临界区上运行,那么这不会成为问题。 It saves an expensive context switch though between user space and kernel space.尽管它在用户空间和内核空间之间节省了昂贵的上下文切换。

std::mutex on the other hand will not keep its core busy.另一方面, std::mutex不会使其核心保持忙碌。 You can't observe a significant load on any of the cores with this solution.使用此解决方案,您无法观察到任何内核上的显着负载。 That's because the thread gets suspended by the scheduler while other threads do some work.那是因为线程被调度程序挂起,而其他线程在做一些工作。 It means that the state of the thread gets stored and then restored and resumed later.这意味着线程的状态被存储,然后恢复并稍后恢复。

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

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