C ++ Mutex是锁定共享资源的唯一方法

时间:2014-10-01 03:44:07

标签: c++ multithreading visual-c++ c++11

除了互斥锁之外,你可以使用什么来锁定C ++?处理器级别有什么可以使用的吗?

3 个答案:

答案 0 :(得分:0)

您可以使用比较和交换,类似于:

std::atomic_bool locked = false;
bool f = false;
... // spawn threads n' stuff
do {
  bool got_lock = atomic_compare_exchange_weak(locked, &f, true);
  if (got_lock) {
     ... // do stuff
     locked = false;
  }
}
while(!got_lock)

我将变量命名为locked和got_lock,但是这里没有真正的锁定。函数atomic_compare_exchange_weak利用特殊的汇编指令作为原子。

要了解它是如何工作的:它进入do while循环并立即尝试CAS。 CAS将lock的值与f中包含的值进行比较,该值为false。当且仅当它们比较相等时,它将锁定为第三个参数(true)并返回true。否则,这意味着已经设置的另一个线程已锁定为true,因此它返回false并且不会更改locked的值。我们可以看到,如果一个线程获得了锁,它会输入if,做一些东西,然后释放锁。如果它没有获得锁定,它不会通过if,但它会被while循环反弹回来。它在这个非常快的while循环中继续,直到CAS调用成功。

所以,在我写完评论"做东西",你可以保证只有一个线程可以同时进行。

答案 1 :(得分:0)

如果您在操作系统下开发,那么您也可以使用信号量。与互斥量相比,信号量可以用一定数量的初始值作为计数器。您启用信号量的值允许任何调用者获取资源或执行关键代码部分,直到值(信号量)大于零。当它下调到零时,任何新的调用者都将等待释放/释放信号量。二进制信号量本身就是互斥量。

答案 2 :(得分:0)

操作系统原语比锁具有关键优势,因为使用OS原语会将您的线程放入内核中的等待队列。释放互斥锁后,操作系统会自动唤醒您的线程并启动。如果您使用比较/交换类型检查,您有责任编写自旋锁并适当地休眠(否则当您没有锁时,您将使用100%的处理器(或核心)等待它释放)。

Mutex在跨进程同步(需要操作系统)方面表现优异。信号量非常相似,只是它允许并发访问关键部分(例如,允许4个线程仅从工作队列运行以优化多核处理器上的工作)。

如果只是在同一进程中同步线程,也可以使用“CRITICAL_SECTION”MSDN LINK。这将更快,因为您不需要系统调用来实现锁定。