函数名
pthread_mutex_lock, pthread_mutex_trylock, pthread_mutex_unlock - 锁住和解锁一个mutex
概要
#include <pthread.h>
int pthread_mutex_lock(pthread_mutex_t *mutex);
int pthread_mutex_trylock(pthread_mutex_t *mutex);
int pthread_mutex_unlock(pthread_mutex_t *mutex);
描述
调用pthread_mutex_lock()
后,被mutex引用的互斥体对象应该被锁住。如果mutex已经被锁住,线程应该被阻塞到mutex可用为止。这个操作返回时,被引用的mutex对象应该处于被调用线程锁住的状态。
如果mutex类型是PTHREAD_MUTEX_NORMAL,死锁检测将不被提供。尝试relock会导致死锁。如果一个线程尝试解锁一个未被锁住的mutex,回答导致未定义的行为。
如果mutex类型是PTHREAD_MUTEX_ERRORCHECK,将会有错误检测。如果一个线程尝试relock一个已经lock的mutex,将会返回一个错误。如果一个线程尝试unlock一个没有lock的mutex或者已经unlock的mutex,也将返回错误。
如果mutex类型是PTHREAD_MUTEX_RECURSIVE,那么mutex将维护一个lock count的概念。当一个线程第一次获取mutex的,lock count将被设置为1,每这个线程lock这个mutex的时候,lock count都会加1,反正则减一。如果lock count被减到0,mutex就可以被其他线程锁住了。如果一个线程尝试unlock一个他没有lock的mutex,将会返回一个错误。
如果mutex类型是PTHREAD_MUTEX_DEFAULT,尝试递归锁定互斥锁会导致未定义的行为。如果互斥锁未被调用线程锁定,则尝试对其进行解锁会导致未定义的行为。如果未锁定互斥锁,则尝试对其进行解锁会导致未定义的行为。
函数 pthread_mutex_trylock()
函数的作用等价于pthread_mutex_lock()
,除了当前由互斥锁引用的互斥对象被锁定(由任何线程(包括当前线程))锁定之外,调用将立即返回。
函数pthread_mutex_unlock()应该释放mutex引用的互斥体。这个调用会导致一个阻塞在这个锁上的线程被解除阻塞状态,获取到这个锁。
如果将信号传递到等待互斥锁的线程,则从信号处理程序返回后,线程应继续等待互斥锁,就好像它没有被中断一样。
Return Value
If successful, the pthread_mutex_lock() and pthread_mutex_unlock() functions shall return zero; otherwise, an error number shall be returned to indicate the error.
The pthread_mutex_trylock() function shall return zero if a lock on the mutex object referenced by mutex is acquired. Otherwise, an error number is returned to indicate the error.
Errors
The pthread_mutex_lock() and pthread_mutex_trylock() functions shall fail if:
EINVAL
The mutex was created with the protocol attribute having the value PTHREAD_PRIO_PROTECT and the calling thread's priority is higher than the mutex's current priority ceiling.
The pthread_mutex_trylock() function shall fail if:
EBUSY
The mutex could not be acquired because it was already locked.
The pthread_mutex_lock(), pthread_mutex_trylock(), and pthread_mutex_unlock() functions may fail if:
EINVAL
The value specified by mutex does not refer to an initialized mutex object.
EAGAIN
The mutex could not be acquired because the maximum number of recursive locks for mutex has been exceeded.
The pthread_mutex_lock() function may fail if:
EDEADLK
The current thread already owns the mutex.
The pthread_mutex_unlock() function may fail if:
EPERM
The current thread does not own the mutex.
These functions shall not return an error code of [EINTR].
The following sections are informative.
Examples
None.
Application Usage
None.
Rationale
Mutex objects are intended to serve as a low-level primitive from which other thread synchronization functions can be built. As such, the implementation of mutexes should be as efficient as possible, and this has ramifications on the features available at the interface.
The mutex functions and the particular default settings of the mutex attributes have been motivated by the desire to not preclude fast, inlined implementations of mutex locking and unlocking.
For example, deadlocking on a double-lock is explicitly allowed behavior in order to avoid requiring more overhead in the basic mechanism than is absolutely necessary. (More "friendly" mutexes that detect deadlock or that allow multiple locking by the same thread are easily constructed by the user via the other mechanisms provided. For example, pthread_self() can be used to record mutex ownership.) Implementations might also choose to provide such extended features as options via special mutex attributes.
Since most attributes only need to be checked when a thread is going to be blocked, the use of attributes does not slow the (common) mutex-locking case.
Likewise, while being able to extract the thread ID of the owner of a mutex might be desirable, it would require storing the current thread ID when each mutex is locked, and this could incur unacceptable levels of overhead. Similar arguments apply to a mutex_tryunlock operation.
网友评论