如何使用重载函数实现互斥锁

时间:2018-04-14 22:04:40

标签: multithreading c++11 overloading

在学习C ++和多线程时,我遇到了关于如何锁定由多个线程调用的共享函数的问题。我明白mutex object会为我做的工作。如果在递归函数上使用互斥对象锁,它将创建一个死锁 - 清除。此外,还有一个特殊的recursive mutex object可用于此类情况 - 也很清楚。

现在我有一组重载函数来为子函数准备数据。那些重叠的函数将被其他线程调用。

我遇到问题,找不到实现互斥锁的正确方法的答案。

示例:互斥锁仅在“Bar()执行”功能Foo(int, int)上。其他Foo函数会调用Foo(int, int),但缺少自己的锁定。

#include <thread>
#include <mutex>

std::mutex m; 
std::thread th;

void one_of_many_threads(void) {
  // Will call one of the Foos ... who knows ...
}

bool Foo(int a, int b) {
  bool result;
  // Lock for others ...    
  m.lock();
  // Do some checks on a and b before sending to Bar.
  // We assume everything is fine ...
  result = Bar(a, b);
  // Unlock for others ...
  m.unlock();
  return result;
}

bool Foo(int a) {
  return Foo(a, 0);
}

bool Foo(void) {
  return Foo(0, 0);
}

bool Bar(int a, int b) {
  // Some magic actions with a, b to modify something ...
  // will return true for now:
  return true;
}

问题1:多个线程调用Foo();Foo(1);时会导致此问题?那些没有锁,可以被调用然后最终变成锁......

问题2:由于还可以调用Foo(int, int),因此在所有Foo函数上使用互斥锁将使递归互斥对象成为必需。但如果对问题1的回答是“没有问题!”,那么在Bar(int, int)函数上实现互斥是否有意义?

感谢您的回答。

1 个答案:

答案 0 :(得分:0)

  

问题1:当Foo()时会引发这个问题;或者Foo(1);被多个线程调用?那些没有锁的人可以被召唤然后最终变成一个锁

不,因为两个Foo函数只调用

bool Foo(int a, int b)

除了“结果”之外,已经有一个互斥体包裹着所有东西。结果 是一个局部变量,它不会导致不同线程之间的数据竞争

  

问题2:因为也可以调用Foo(int,int),所以在所有Foo函数上使用互斥锁将使递归互斥对象成为必要。但是如果对问题1的回答是&#34;没有问题!&#34;,在Bar(int,int)函数上实现互斥量是否有意义?

如果只能通过Foo函数调用Bar,则无需在Bar中添加额外的互斥锁,因为Bar已经位于Foo中的互斥锁内。

如果Bar可以在任何地方自由调用(如果它访问/修改某些全局/共享资源),那么是的,你最好放一个互斥锁(即不同的互斥对象,或者你提到的recursive_mutex)防止竞争条件(和Foo的僵局)。

但是,您当前的示例中只有局部变量。如果您只使用本地对象/副本,则根本不需要任何互斥锁。