【问题标题】:C++ Pass Mutex By Reference for Different InstancesC ++通过引用为不同实例传递互斥锁
【发布时间】:2016-12-27 13:56:18
【问题描述】:

我想在一个类的不同实例之间共享一个互斥体,其函数作为线程运行。我写的方法好吗? (我认为我不需要使用 shared_mutex,尽管这可能是更好的做法。我会以同样的方式传递它吗?)

class A
{
 public:

     // Execute some work that locks some piece of data by acquiring the mutex.
     void execute(std::mutex & myMutex);
}

class B
{

 public:
     void execute(std::shared_ptr<A> a)
     {

        //   Create the Threads for execution.
        //   Changed to correct syntax.
        std::thread t1(&B::runThread, this, a);
        std::thread t2(&B::runThread, this, a);

        t1.join();            
        t2.join();
     };

     void runThread(std::shared_ptr<A> a)
     {
         a->execute(std::ref(theMutex));
     }



 private:

 //   The Mutex to share with the threads.
 std::mutex theMutex;

}

【问题讨论】:

  • 为什么不让线程(函数)成为类的成员呢?
  • 我进行了编辑以使用例更清晰,但本质上我想从 A 类派生并稍后将其传递。然后 A 的派生类可以使用它认为合适的互斥锁。

标签: c++ multithreading c++11 thread-safety mutex


【解决方案1】:

首先,发布的代码无法编译:B::runThread() 是非static 成员,因此将隐式对象作为参数。您需要使用以下方法创建线程:

std::thread t(&B::runThread, this, a);

假设B::theMutex 在使用A::execute() 时确实适当地保护了多个线程之间共享的资源,那么在不同线程之间共享互斥锁的方法就是互斥锁的用途。由于这个问题没有任何细节,因此无法回答互斥锁是否是适当的同步原语:根据A::execute() 中的实际使用情况,其他方法可能更适合避免序列化、死​​锁等。

使用std::shared_mutex 基本上在所有情况下都是错误的方法,并且肯定不是“更好的做法”。 std::shared_mutex 实际上确实会导致更好的方法的情况极为罕见。在实践中,我从未见过使用std::shared_mutex 之类的东西会提高性能的情况(我还没有在野外看到std::shared_mutex,但是POSIX 计数器部件或包装器我经常遇到令人惊讶的情况)。相反,它总是导致比使用普通std::mutexes 更差的性能,并且它具有极其糟糕的最坏情况行为:当有大量更改(即独占锁)时,它经常导致整个系统的严重停顿。

【讨论】:

  • 好的。我只是想确定一下。假设B::theMutex 在只有一个线程获取共享资源时确实保护了它。因此,即使每个线程都获得了对互斥锁的引用,但当一个线程尝试锁定它时,只有该线程会获取互斥锁,对吧?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2010-09-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-22
  • 2022-07-31
  • 1970-01-01
相关资源
最近更新 更多