操作 |
相关函数说明 |
---|---|
初始化互斥锁 |
pthread_mutex_init 语法 |
使互斥锁保持一致 |
pthread_mutex_consistent_np 语法 |
锁定互斥锁 |
pthread_mutex_lock 语法 |
解除锁定互斥锁 |
pthread_mutex_unlock 语法 |
使用非阻塞互斥锁锁定 |
pthread_mutex_trylock 语法 |
销毁互斥锁 |
pthread_mutex_destroy 语法 |
缺省调度策略 SCHED_OTHER不指定线程可以获取锁的顺序。如果多个线程正在等待一个互斥锁,则获取顺序是不确定的。出现争用时,缺省行为是按优先级顺序解除线程的阻塞。
使用 pthread_mutex_init(3C) 可以使用缺省值初始化由 mp所指向的互斥锁,还可以指定已经使用 pthread_mutexattr_init()设置的互斥锁属性。mattr 的缺省值为 NULL。对于 Solaris线程,请参见mutex_init(3C)语法。
int pthread_mutex_init(pthread_mutex_t *mp, const pthread_mutexattr_t *mattr);
#include <pthread.h> pthread_mutex_t mp = PTHREAD_MUTEX_INITIALIZER; pthread_mutexattr_t mattr; int ret; ret = pthread_mutex_init(&mp, NULL); ret = pthread_mutex_init(&mp, &mattr);
如果互斥锁已初始化,则它会处于未锁定状态。互斥锁可以位于进程之间共享的内存中或者某个进程的专用内存中。
注 –初始化互斥锁之前,必须将其所在的内存清零。
将 mattr 设置为 NULL的效果与传递缺省互斥锁属性对象的地址相同,但是没有内存开销。
使用 PTHREAD_MUTEX_INITIALIZER宏可以将以静态方式定义的互斥锁初始化为其缺省属性。
当其他线程正在使用某个互斥锁时,请勿重新初始化或销毁该互斥锁。如果任一操作没有正确完成,将会导致程序失败。如果要重新初始化或销毁某个互斥锁,则应用程序必须确保当前未使用该互斥锁。
pthread_mutex_init()在成功完成之后会返回零。其他任何返回值都表示出现了错误。如果出现以下任一情况,该函数将失败并返回对应的值。
EBUSY
描述:该实现已检测到系统尝试重新初始化 mp 所引用的对象,即以前进行过初始化但 尚未销毁的互斥锁。
EINVAL
描述:mattr 属性值无效。互斥锁尚未修改。
EFAULT
描述:mp 所指向的互斥锁的地址无效。
如果某个互斥锁的属主失败,该互斥锁可能会变为不一致。
使用pthread_mutex_consistent_np 可使互斥对象 mutex在其属主停止之后保持一致。
#include <pthread.h> int pthread_mutex_consistent_np(pthread_mutex_t *mutex);注 –
仅当定义了 _POSIX_THREAD_PRIO_INHERIT符号时,pthread_mutex_consistent_np()才适用,并且仅适用于使用协议属性值 PTHREAD_PRIO_INHERIT 初始化的互斥锁。
调用 pthread_mutex_lock()会获取不一致的互斥锁。EOWNWERDEAD 返回值表示出现不一致的互斥锁。
持有以前通过调用 pthread_mutex_lock() 获取的互斥锁时可调用pthread_mutex_consistent_np()。
如果互斥锁的属主失败,则该互斥锁保护的临界段可能会处于不一致状态。在这种情况下,仅当互斥锁保护的临界段可保持一致时,才能使该互斥锁保持一致。
针对互斥锁调用pthread_mutex_lock()、pthread_mutex_unlock()和 pthread_mutex_trylock() 会以正常方式进行。
对于不一致或者未持有的互斥锁,pthread_mutex_consistent_np()的行为是不确定的。
pthread_mutex_consistent_np()在成功完成之后会返回零。其他任何返回值都表示出现了错误。
pthread_mutex_consistent_np() 会在出现以下情况时失败:
ENOSYS
描述:选项 _POSIX_THREAD_PRIO_INHERIT 未定义,或者该实现不支持pthread_mutex_consistent_np()。
pthread_mutex_consistent_np()可能会在出现以下情况时失败:
EINVAL
描述:mattr 属性值无效。
使用 pthread_mutex_lock(3C) 可以锁定 mutex 所指向的互斥锁。
int pthread_mutex_lock(pthread_mutex_t *mutex);
#include <pthread.h> pthread_mutex_t mutex; int ret; ret = pthread_ mutex_lock(&mp);
当 pthread_mutex_lock()返回时,该互斥锁已被锁定。调用线程是该互斥锁的属主。如果该互斥锁已被另一个线程锁定和拥有,则调用线程将阻塞,直到该互斥锁变为可用为止。对于 Solaris 线程,请参见mutex_lock语法。
如果互斥锁类型为PTHREAD_MUTEX_NORMAL,则不提供死锁检测。尝试重新锁定互斥锁会导致死锁。如果某个线程尝试解除锁定的互斥锁不是由该线程锁定或未锁定,则将产生不确定的行为。
如果互斥锁类型为PTHREAD_MUTEX_ERRORCHECK,则会提供错误检查。如果某个线程尝试重新锁定的互斥锁已经由该线程锁定,则将返回错误。如果某个线程尝试解除锁定的互斥锁不是由该线程锁定或者未锁定,则将返回错误。
如果互斥锁类型为PTHREAD_MUTEX_RECURSIVE,则该互斥锁会保留锁定计数这一概念。线程首次成功获取互斥锁时,锁定计数会设置为1。线程每重新锁定该互斥锁一次,锁定计数就增加 1。线程每解除锁定该互斥锁一次,锁定计数就减小 1。 锁定计数达到 0时,该互斥锁即可供其他线程获取。如果某个线程尝试解除锁定的互斥锁不是由该线程锁定或者未锁定,则将返回错误。
如果互斥锁类型是PTHREAD_MUTEX_DEFAULT,则尝试以递归方式锁定该互斥锁将产生不确定的行为。对于不是由调用线程锁定的互斥锁,如果尝试解除对它的锁定,则会产生不确定的行为。如果尝试解除锁定尚未锁定的互斥锁,则会产生不确定的行为。
pthread_mutex_lock()在成功完成之后会返回零。其他任何返回值都表示出现了错误。如果出现以下任一情况,该函数将失败并返回对应的值。
EAGAIN
描述:由于已超出了互斥锁递归锁定的最大次数,因此无法获取该互斥锁。
EDEADLK
描述:当前线程已经拥有互斥锁。
如果定义了 _POSIX_THREAD_PRIO_INHERIT 符号,则会使用协议属性值PTHREAD_PRIO_INHERIT 对互斥锁进行初始化。此外,如果pthread_mutexattr_setrobust_np() 的robustness 参数是PTHREAD_MUTEX_ROBUST_NP,则该函数将失败并返回以下值之一:
EOWNERDEAD
描述:该互斥锁的最后一个属主在持有该互斥锁时失败。该互斥锁现在由调用方拥有。调用方必须尝试使该互斥锁所保护的状态一致。
如果调用方能够使状态保持一致,请针对该互斥锁调用pthread_mutex_consistent_np() 并解除锁定该互斥锁。以后对pthread_mutex_lock() 的调用都将正常进行。
如果调用方无法使状态保持一致,请勿针对该互斥锁调用pthread_mutex_init(),但要解除锁定该互斥锁。以后调用pthread_mutex_lock() 时将无法获取该互斥锁,并且将返回错误代码ENOTRECOVERABLE。
如果获取该锁的属主失败并返回 EOWNERDEAD,则下一个属主获取该锁时将返回EOWNERDEAD。
ENOTRECOVERABLE
描述:尝试获取的互斥锁正在保护某个状态,此状态由于该互斥锁以前的属主在持有该锁时失败而导致不可恢复。尚未获取该互斥锁。如果满足以下条件,则可能出现此不可恢复的情况:
以前获取该锁时返回 EOWNERDEAD
该属主无法清除此状态
该属主已经解除锁定了该互斥锁,但是没有使互斥锁状态保持一致
ENOMEM
描述:已经超出了可同时持有的互斥锁数目的限制。
使用 pthread_mutex_unlock(3C) 可以解除锁定 mutex 所指向的互斥锁。 对于Solaris 线程,请参见mutex_unlock语法。
int pthread_mutex_unlock(pthread_mutex_t *mutex);
#include <pthread.h> pthread_mutex_t mutex; int ret; ret = pthread_mutex_unlock(&mutex);
pthread_mutex_unlock() 可释放 mutex引用的互斥锁对象。互斥锁的释放方式取决于互斥锁的类型属性。 如果调用pthread_mutex_unlock() 时有多个线程被 mutex对象阻塞,则互斥锁变为可用时调度策略可确定获取该互斥锁的线程。 对于 PTHREAD_MUTEX_RECURSIVE类型的互斥锁,当计数达到零并且调用线程不再对该互斥锁进行任何锁定时,该互斥锁将变为可用。
pthread_mutex_unlock()在成功完成之后会返回零。其他任何返回值都表示出现了错误。如果出现以下情况,该函数将失败并返回对应的值。
EPERM
描述:当前线程不拥有互斥锁。
使用 pthread_mutex_trylock(3C) 可以尝试锁定 mutex 所指向的互斥锁。对于Solaris 线程,请参见mutex_trylock语法。
int pthread_mutex_trylock(pthread_mutex_t *mutex);
#include <pthread.h> pthread_mutex_t mutex; int ret; ret = pthread_mutex_trylock(&mutex);
pthread_mutex_trylock() 是pthread_mutex_lock() 的非阻塞版本。如果 mutex所引用的互斥对象当前被任何线程(包括当前线程)锁定,则将立即返回该调用。否则,该互斥锁将处于锁定状态,调用线程是其属主。
pthread_mutex_trylock()在成功完成之后会返回零。其他任何返回值都表示出现了错误。如果出现以下任一情况,该函数将失败并返回对应的值。
EBUSY
描述:由于 mutex 所指向的互斥锁已锁定,因此无法获取该互斥锁。
EAGAIN
描述:由于已超出了 mutex 的递归锁定最大次数,因此无法获取该互斥锁。
如果定义了 _POSIX_THREAD_PRIO_INHERIT 符号,则会使用协议属性值PTHREAD_PRIO_INHERIT 对互斥锁进行初始化。此外,如果pthread_mutexattr_setrobust_np() 的robustness 参数是PTHREAD_MUTEX_ROBUST_NP,则该函数将失败并返回以下值之一:
EOWNERDEAD
描述:该互斥锁的最后一个属主在持有该互斥锁时失败。该互斥锁现在由调用方拥有。调用方必须尝试使该互斥锁所保护的状态一致。
如果调用方能够使状态保持一致,请针对该互斥锁调用pthread_mutex_consistent_np() 并解除锁定该互斥锁。以后对pthread_mutex_lock() 的调用都将正常进行。
如果调用方无法使状态保持一致,请勿针对该互斥锁调用pthread_mutex_init(),而要解除锁定该互斥锁。以后调用pthread_mutex_trylock() 时将无法获取该互斥锁,并且将返回错误代码ENOTRECOVERABLE。
如果已获取该锁的属主失败并返回 EOWNERDEAD,则下一个属主获取该锁时返回EOWNERDEAD。
ENOTRECOVERABLE
描述:尝试获取的互斥锁正在保护某个状态,此状态由于该互斥锁以前的属主在持有该锁时失败而导致不可恢复。尚未获取该互斥锁。以下条件下可能会出现此情况:
以前获取该锁时返回 EOWNERDEAD
该属主无法清除此状态
该属主已经解除锁定了该互斥锁,但是没有使互斥锁状态保持一致
ENOMEM
描述:已经超出了可同时持有的互斥锁数目的限制。
使用 pthread_mutex_destroy(3C) 可以销毁与 mp 所指向的互斥锁相关联的任何状态。对于 Solaris 线程,请参见mutex_destroy语法。
int pthread_mutex_destroy(pthread_mutex_t *mp);
#include <pthread.h> pthread_mutex_t mp; int ret; ret = pthread_mutex_destroy(&mp);
请注意,没有释放用来存储互斥锁的空间。
pthread_mutex_destroy()在成功完成之后会返回零。其他任何返回值都表示出现了错误。如果出现以下任一情况,该函数将失败并返回对应的值。
EINVAL
描述:mp 指定的值不会引用已初始化的互斥锁对象。