可以定义任意数量的互斥量(受限于RAM)。每个互斥量通过其内存地址进行引用。
互斥量的关键属性如下:
互斥量必须先初始化再使用。初始化时会将其锁计数设为 0。
当一个线程想使用共享资源时,它必须先锁定互斥量以获得专有的访问权限。如果该互斥锁已被另一个线程锁定,请求线程可以等待该互斥量被解锁。
锁定互斥量后,线程可以长时间安全地使用相关联的资源。不过,一个好的做法是尽可能短的持有互斥量,因为这样能避免对其它需要使用这些资源的线程造成影响。当线程不再需要使用资源时,必须将互斥量 解锁,以允许其它线程可以使用该资源。
多个线程可以同时等待某个被锁定的互斥量。当该互斥量被解锁后,它会被优先级最高的、等待时间最久的线程所使用。
NOTE
不能在中断中使用互斥量。
线程可以锁定一个已经锁定的互斥量。这样做的好处是线程可以在执行的某个时刻(互斥量可能被锁定也可能未被锁定)访问该互斥量所关联的资源。
互斥量被一个线程多次锁定后,它必须被解锁相同的次数后才能被其它线程所获取到。
已锁定互斥量的线程具有 优先级继承(priority inheritance) 的能力。这意味着,如果有一个高优先级的线程开始等待这个互斥量,内核将 临时 提升占用互斥量线程的优先级。这样做的好处是,占用互斥量的线程可以与等待线程相同的优先级继续执行而不会被其抢占,因此可以更快速地执行并释放互斥量。互斥量一旦被解锁后,该线程的优先级会被恢复至锁定该互斥量前的优先级。
NOTE
内核由于优先级继承而提升线程的优先级时,配置选项 CONFIG_PRIORITY_CEILING 会限制其所能提升的最大优先级。默认值 0 允许内核可以对其进行无限制的提升。
当所属线程获得锁时,它的基本优先级保存在互斥锁中。每当有更高优先级的线程在互斥锁上等待时,内核就会调整所属线程的优先级。 当所属线程释放锁时(或者高优先级等待线程超时),内核将根据互斥锁中保存的值恢复线程的基本优先级。
只要只涉及一个互斥锁,这种方法就可以很好地用于优先级继承。但是,如果涉及多个互斥锁,如果互斥锁没有按照先前提升所属线程优先级的相反顺序解锁,则会看到次优行为。因此,当多个互斥量在不同的优先级的线程之间共享时,建议同一时刻只锁定一个互斥量。