简单数据类型的互斥锁

Mutex for simple data types

本文关键字:数据类型 简单      更新时间:2023-10-16

我对并发性很陌生,我在决定如何使用互斥锁时遇到了麻烦。目前,它们散布在两个线程交互的代码中。这样使用互斥锁是合适的吗?

class Foo
{
public:
    void SetMember(int n) {  AcquireMutex(..); n_ = n; ReleaseMutex(...);}
private:
   Thread()
   {
      while(1)
      {
         AcquireMutex(..);
         // Do something with n_
         ReleaseMutex(...);
       }
   }
};

我有相当多的数据成员可以由不同的线程从外部读取和设置,我发现跟踪所有获取和释放互斥锁是一件令人头痛的事情。

基本类型的突变不能保证是线程安全的,或者更确切地说是原子性的。事实上,如果您查看<atomic>,您会注意到有几个专门化,包括std::atomic_int

从cppreference

原子类型的对象是c++中唯一没有数据竞争的对象;也就是说,如果一个线程写一个原子对象,而另一个线程从它读,行为是良好定义的。

具体回答你关于使用互斥锁的问题,是的,你在你的例子中使用互斥锁是好的。一般来说,您希望保持互斥锁的时间越短越好。换句话说,如果你有一个做很多工作的函数,只锁定非线程安全代码周围的互斥锁,然后在代码是线程安全的时候解锁它。

这种互斥方法非常幼稚,它无法避免死锁和其他并发性问题。

您必须明确地标识代码中两个进程同时访问会导致问题的地方,并将它们保护在临界区。你必须确保你不会让两个进程开始一个操作,因为另一个进程无法完成。

在其他地方,可能不需要保护,激活互斥锁是多余的。

通常,原子性不是单个变量所需要的,而是一组耦合变量所需要的