c++ - 类和互斥量

标签 c++ multithreading c++11 mutex

假设我有一个类代表一些名为 foo 的数据结构:

class foo{
  public:
    foo(){
      attr01 = 0;
    }
    void f(){
      attr01 += 5;
    }
  private:
    int attr01;
};

class fooSingleThreadUserClass{
    void usefoo(){
      fooAttr.f();
    }

    foo fooAttr;
}

现在假设以后在软件构建中,我发现我需要多线程。我应该在 foo 中添加互斥量吗?

class foo{
  public:
    foo(){
      attr01 = 0;
    }
    void f(){
      attr01Mutex.lock();
      attr01 += 5;
      attr01Mutex.unlock();
    }
  private:
    int attr01;
    std::mutex attr01Mutex;
};

class fooMultiThreadUserClass{
    void usefoo(){
      std::thread t1(&fooMultiThreadUserClass::useFooWorker, this);
      std::thread t2(&fooMultiThreadUserClass::useFooWorker, this);
      std::thread t3(&fooMultiThreadUserClass::useFooWorker, this);
      std::thread t4(&fooMultiThreadUserClass::useFooWorker, this);

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

    void useFooWorker(){
      fooAttr.f();
    }

    foo fooAttr;
}

我知道 fooMultiThreadUserClass 现在可以在没有竞争的情况下以高性能运行 foo,但是 fooSingleThreadUserClass 会因为互斥开销而降低性能吗?我很想知道。或者我应该出于并发目的从 foo 派生 fooCC,以便 fooSingleThreadUserClas 可以继续使用没有互斥锁的 foo,而 fooMultiThreadUserClass 使用带有互斥锁的 fooCC,如下所示

class fooCC : public foo{
  public:
    foo(){
      attr01 = 0;
    }
    void f(){  // I assume that foo::f() is now a virtual function.
      attr01Mutex.lock();
      foo::f();
      attr01Mutex.unlock();
    }
  private:
    std::mutex attr01Mutex;
};

还假设编译器优化已经处理了虚拟调度。我想知道我应该使用继承还是简单地将互斥锁放在原始类中。

我已经搜索过 Stackoverflow,但我想我的问题有点太具体了。

编辑:请注意,不必只有一个参数,这个问题是抽象的,具有 n 个参数的类。

最佳答案

使用std::lock_guard . lock_guard需要 mutex在它的构造函数中。在施工期间,lock_guard锁定 mutex .当 lock_guard超出范围,其析构函数会自动释放锁。

class foo
{
private:
  std::mutex mutex;
  int attr01;

public:
  foo() {
    attr01 = 0;
  }

  void f(){
    std::lock_guard<std::mutex> lock (mutex);
    attr01 += 5;
  }
};

你可以把mutablemutex 上如果您需要能够锁定或解锁 mutex来自 const功能。我通常离开mutable关闭 mutex直到我特别需要它。

它会失去性能吗?这取决于。如果您调用该函数一百万次,那么创建 mutex 的开销可能会增加会成为一个问题(它们并不便宜)。如果函数执行时间很长,并且被许多线程频繁调用,那么快速阻塞可能会影响性能。如果您无法确定具体问题,只需使用 std::lock_guard .

Hans Passant 提出了一个超出您问题范围的合理担忧。我认为 Herb Sutter(?)在他的一篇网站文章中写过这个。不幸的是我现在找不到它。要了解为什么多线程如此困难,以及为什么对单个数据字段的锁定“不够”,请阅读一本关于多线程编程的书,例如 C++ Concurrency in Action: Practical Multithreading

关于c++ - 类和互斥量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24225201/

相关文章:

c++ - crypto++ rsa key 进入缓冲区

c - 注册一个新的线程处理程序,如 pthread_atfork 或 atexit

java - 等待线程中的特定条件变为真

c++ - 在无法访问的语句中创建变量是否是明确定义的行为?

c++ - if else 条件错误

c++ - 将 G 代码解释为电机控制信号

c++ - 当 typedef 名称与可变参数模板参数名称一致时出现 GCC 错误

c++ - transform_reduce 中的推力异常 bulk_kernel_by_value

c++ - 如何编译openCV保证单线程?

c++ - 不锁定 pthread_cond_timedwait 和 pthread_cond_signal 的互斥量(在 Linux 上)