用QMutex可以实现线程互斥 (线程同步)
互斥+有序=同步, 在win7和win10上线程调度合理, 互斥即同步

1 QMutex

(1) QMutex::QMutex(mode)

构造一个新的互斥量。
互斥锁以解锁状态创建。
如果mode为 QMutex::Recursive ,则线程可以多次锁定同一个互斥锁,
并且只有在进行了相应数量的unlock()调用后,该互斥锁才会被解锁。
否则,一个线程只能锁定一个互斥锁一次。
默认值为QMutex :: NonRecursive。
与非递归互斥锁相比,递归互斥锁较慢并且占用更多内存。

(2) void QMutex::lock()

锁定互斥锁。
如果另一个线程锁定了互斥锁,则该调用将一直阻塞,直到该线程将其解锁为止。
如果此互斥锁是递归互斥锁,则允许从同一线程在同一互斥锁上多次调用此函数。
如果此互斥锁是非递归互斥锁,则该功能将在递归锁定互斥锁时死锁。

(3) bool QMutex::tryLock(int timeout=0)

尝试锁定互斥锁。
如果获得了锁定,则此函数返回true;否则,返回false。
否则返回false。
如果另一个线程锁定了互斥锁,则此功能将最多等待超时毫秒,以使该互斥锁可用。
注意:由于超时而传递负数等同于调用lock(),即如果超时为负,则此函数将永远等待直到互斥锁可以被锁定。
如果获得了锁定,则互斥锁必须在另一个线程成功锁定之前使用unlock()进行解锁。
如果此互斥锁是递归互斥锁,则允许从同一线程在同一互斥锁上多次调用此函数。
如果此互斥锁是非递归互斥锁,则在尝试递归锁定互斥锁时,此函数将始终返回false。

注: try_lock() 等价于 tryLock(0)

(4) void QMutex::unlock()

解锁互斥锁。
尝试用与锁定互斥锁不同的线程解锁互斥锁会导致错误。
解锁未锁定的互斥锁会导致未定义的行为。

2 QMutexLocker

此类的实例对象locker, 构造时会自动lock, 析构时自动unlock
注意: 在PySide2中QMutexLocker不可用

  1. QMutexLocker
  2. #include <QMutexLocker>
  3. QMutex mutex(QMutex::Recursive);
  4. int number = 6;
  5. void method1()
  6. {
  7. QMutexLocker locker(&mutex);
  8. number *= 5;
  9. // Here locker goes out of scope.
  10. // When locker is destroyed automatically unlocks mutex
  11. }
  12. void method2()
  13. {
  14. QMutexLocker locker(&mutex);
  15. number *= 3;
  16. }

3 在PySide2中, 是否可用with QMutex?

不可用, 因为QMutex类未定义enterexit魔法方法
image.png