跳到主要内容

互斥量

mutex 互斥量

互斥算法避免多个线程同时访问共享资源。这会避免数据竞争,并提供线程间的同步支持。 4 种互斥量类型

mutex


基本互斥量,mutex变量上锁后,在一个时间段内,只允许一个线程访问他。

class mutex;

特点

  • 提供排他性非递归所有权语义:
    • 调用方线程从成功调用locktry_lock开始,到他调用unlock为止,占用mutex
    • 其他线程若试图要求被占用的mutex的所有权时,将阻塞 (lock) 或受到False返回值 (try_lock)
    • 调用方在调用locktry_lock前必须不占有 mutex
  • mutex在仍被占有时被销毁,或占有mutex时线程终止,则行为未定义
  • mutex既不可复制也不可移动

成员函数(部分)

  • lock(): 要求获取锁,若锁已被另一线程获取,则将阻塞进程直到获得锁。若lock被已占有锁mutex的线程调用,则行为未定义,例如可能导致死锁或抛出std::system_error。在抛出错误时,不锁定锁
  • try_lock(): 尝试锁定锁,立即返回,成功时返回true,否则返回false。已占有锁的线程调用该锁的 try_lock,行为未定义。
  • unlock(): 解锁互斥,互斥必须为当前线程所锁定,否则行为为定义

timed_mutex


类似mutex,提供排他性非递归所有权语义,另外提供通过try_lock_for()try_lock_until()方法试图带时限地要求timed_mutex所有权。

class timed_mutex;

成员函数(部分)

  • try_lock_for(): 尝试给互斥上锁。阻塞直到经过指定的timeout_duration或者得到锁。成功获得锁后返回true,否则返回false
    • timeout_duration小于或等于timeout_duration.zero(),则函数表现同try_lock()
  • try_lock_until(): 尝试给锁互斥,阻塞直到抵达指定的timeout_time或得到锁,成功得到锁时返回true,否则返回false

recursive_mutex


递归锁

class recursive_mutex;

特点

  • 提供排他性递归所有权语义:
    • 调用方线程在从它成功锁互斥开始的时期占有recursive_mutex,在此期间,线程可进行对locktry_lock的附加调用。所有权的时期在线程调用unlock匹配次数时结束
    • 其他线程试图要求被占有的recursive_mutex时,被阻塞或受到false返回值
    • 可锁定recursive_mutex次数的最大值是未指定的,但抵达该数后,对 lock 的调用将抛出std::system_error,而对try_lock的调用将返回false

recursive_timed_mutex


定时递归互斥锁

class recursive_timed_mutex;

通用互斥管理

lock_guard


互斥体包装器,为在作用域期间占有互斥提供便利 RAII 风格机制。创建时,获取提供的互斥锁的所有权,控制流离开lock_guard作用域时,自动析构并释放互斥量

template< class Mutex >
class lock_guard;

特点

  • 创建即加锁,作用域结束自动析构,无需手动解锁
  • 不能中途解锁,必须等待作用域结束
  • 不能复制

(C++17 起,std::scoped_lock给出lock_guard的一种替代,有避免死锁的算法提供锁定多个互斥体的能力)

unique_lock


通用互斥包装器,允许延迟锁定、锁定的有时限尝试、递归锁定、所有权转移和与条件变量一同使用。

template< class Mutex >
class unique_lock;

特点

  • 创建时可以不锁定
  • 随时加锁解锁
  • 作用域规则同lock_guard,析构自动释放锁
  • 不可复制,可移动
  • 条件变量condition_variable需要该类型的锁为参数

成员函数(部分)

  • operator=: 若占有则解锁互斥,并取得另一者的所有权
  • swap(): 与另一unique_lock交换状态
  • release(): 将关联的互斥解关联而不解锁它,并返回互斥的指针,若无关联的互斥,则返回空指针
  • mutex(): 返回指向关联互斥的指针,若无关联互斥,则返回空指针
  • owns_lock(): 检查*this是否占有锁定的互斥,若拥有关联互斥且已获得其所有权则为true,否则为false
  • operator bool: 等效调用owns_lock()

指定锁定策略的标签常量

  • defer_lock: defer_lock_t的实例,不获得互斥的所有权
  • try_to_lock: try_to_lock_t的实例,尝试获得互斥所有权而不阻塞
  • adopt_lock_t: adopt_lock_t的实例,假设调用方线程已拥有互斥的所有权