互斥锁可以保护相对于特定指针的数据吗?

时间:2018-08-10 11:20:52

标签: c++ qt mutex

我的Qt应用使用QMutexQMutexLocker来确保线程安全。

互斥锁是否保护功能的数据或范围?

例如:

class Counter
{
public:
  Counter() { *ptr; }
  void setObject(MyClass *pr){ptr = pr;}

  void increment() { QMutexLocker locker(&mutex); //dowork for ptr; }
  void decrement() { QMutexLocker locker(&mutex); //dowork for pointer to MyClass, ptr; }

private:
  mutable QMutex mutex;
  MyClass *ptr;
};

//Thread...
Counter counter;
MyClass *mclass= new MyClass;
//setting... mclass
counter.setOjbect(mclass);

OtherClass oc;  //This `OtherClass` also works for mclass same as the value of Counter.
oc.setObject(mclass);  //Counter and OtherClass work for mclass.
 //Mutex protect mclass data?

指向MyClass的指针可以在其他一些类中使用。

QMutexLocker是保护ptr的数据还是仅保护多次调用中的访问功能incrementdecrement

如何保护ptr处的数据?

1 个答案:

答案 0 :(得分:1)

确保使用同一QMutex实例的所有线程互斥,例如它保护数据。因此,另一个类无法同步其对MyClass的访问,因为它无法访问互斥体(除非您可以确保两个线程不会碰到相同的成员字段)。

您应确保访问MyClass实例的每个人都使用相同的互斥体实例。可以通过以下方式完成:

  • 将互斥锁移动到MyClass实例。这是您最可能需要的。
  • 使用单个全局互斥量池,并使用MyClass实例地址为其选择一个互斥量。

后一种方法如下所示:

const std::size_t SIZE = 47; // prime numbers work better here
statuc QMutex g_mtx[SIZE];

QMutex &get_mutex(const void *ptr)
{
    return g_mtx[std::uintptr_t(ptr) % SIZE];
}

要保护指向MyClass的{​​{1}}指针的实例,您应该使用ptr。如果QMutexLocker(get_mutex(ptr))是一个很小的对象并且大量存在,这很有用,因此为每个实例保留一个单独的互斥量会成为一个问题。