以下的头文件来自linux 2.6.18
PTHREAD_MUTEX_LOCK(P) POSIX Programmer’s Manual PTHREAD_MUTEX_LOCK(P)
NAME
pthread_mutex_lock, pthread_mutex_trylock, pthread_mutex_unlock - lock and unlock a mutex
int pthread_mutex_lock(pthread_mutex_t *mutex);
int pthread_mutex_trylock(pthread_mutex_t *mutex);
int pthread_mutex_unlock(pthread_mutex_t *mutex);
DESCRIPTION
The mutex object referenced by mutex shall be locked by calling pthread_mutex_lock(). If the mutex is already locked, the calling
thread shall block until the mutex becomes available. This operation shall return with the mutex object referenced by mutex in the
locked state with the calling thread as its owner.
--------mutex对象通过调用函数pthread_mutex_lock()来锁住。如果mutex已经被锁住,调用线程被阻塞直到mutex可用。该函数返回时,mutex被锁住同时调用线程成为
mutex的拥有者。
If the mutex type is PTHREAD_MUTEX_NORMAL, deadlock detection shall not be provided. Attempting to relock the mutex causes deadlock.
If a thread attempts to unlock a mutex that it has not locked or a mutex which is unlocked, undefined behavior results.
--------如果mutex的类型为PTHREAD_MUTEX_NORMAL,不会提供死锁检测机制。企图进行relock mutex将会导致死锁。如果一个线程尝试unlock一个没有被锁住的或者已经
被unlock的mutex,将会导致不可预料的结果。
mutex的定义如下:
typedef struct
{
int __m_reserved; /* Reserved for future use */
int __m_count; /* Depth of recursive locking */
_pthread_descr __m_owner; /* Owner thread (if recursive or errcheck) */
int __m_kind; /* Mutex kind: fast, recursive or errcheck */
struct _pthread_fastlock __m_lock; /* Underlying fast lock */
} pthread_mutex_t;
常见的mutex的定义方法如下:
pthread_mutex_t g_TestMutex = PTHREAD_MUTEX_INITIALIZER;
在pthread.h中有如下定义:
#define PTHREAD_MUTEX_INITIALIZER \
{0, 0, 0, PTHREAD_MUTEX_ADAPTIVE_NP, __LOCK_INITIALIZER}
enum
{
...
PTHREAD_MUTEX_NORMAL = PTHREAD_MUTEX_ADAPTIVE_NP,
...
}
从上可知上述的定义方法,是不提供死锁检测的,可能导致死锁问题。
If the mutex type is PTHREAD_MUTEX_ERRORCHECK, then error checking shall be provided. If a thread attempts to relock a mutex that it
has already locked, an error shall be returned. If a thread attempts to unlock a mutex that it has not locked or a mutex which is
unlocked, an error shall be returned.
-------如果mutex的类型为PTHREAD_MUTEX_ERRORCHECK,那么则提供错误检测。如果一个线程尝试relock一个已经锁住的mutex,将会返回一个错误。如果尝试unlock一个
没有被锁住或已经被unlock的mutex,将返回一个错误。
定义方法:pthread_mutex_t g_TestMutex = PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP;
在pthread.h中有如下定义:
#ifdef __USE_GNU
# define PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP \
{0, 0, 0, PTHREAD_MUTEX_ERRORCHECK_NP, __LOCK_INITIALIZER}
#endif
If the mutex type is PTHREAD_MUTEX_RECURSIVE, then the mutex shall maintain the concept of a lock count. When a thread successfully
acquires a mutex for the first time, the lock count shall be set to one. Every time a thread relocks this mutex, the lock count shall
be incremented by one. Each time the thread unlocks the mutex, the lock count shall be decremented by one. When the lock count reaches
zero, the mutex shall become available for other threads to acquire. If a thread attempts to unlock a mutex that it has not locked or
a mutex which is unlocked, an error shall be returned.
--------如果mutex的类型是PTHREAD_MUTEX_RECURSIVE,那么mutex将维护一个锁住次数。当一个线程第一次成功的获取此mutex,锁住次数被设为1.每次这个线程relock此
mutex,锁住次数增加1。每次这个线程unlock此mutex,锁住次数减一。当锁住次数成为0时,此mutex可以重新被其他线程获取。如果一个线程尝试unlock没有锁住或已经被unlock
的mutex,将返回一个错误。
定义方法:pthread_mutex_t g_TestMutex = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
在pthread.h中有如下定义:
#ifdef __USE_GNU
# define PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP \
{0, 0, 0, PTHREAD_MUTEX_RECURSIVE_NP, __LOCK_INITIALIZER}
#endif
If the mutex type is PTHREAD_MUTEX_DEFAULT, attempting to recursively lock the mutex results in undefined behavior. Attempting to
unlock the mutex if it was not locked by the calling thread results in undefined behavior. Attempting to unlock the mutex if it is not
locked results in undefined behavior.
--------如果mutex的类型是PTHREAD_MUTEX_DEFAULT,尝试递归锁住mutex将导致不可预料的结果。尝试unlock一个没有被锁住的mutex是一个未定义的行为。
在pthread.h的文件中,PTHREAD_MUTEX_DEFAULT 等同于PTHREAD_MUTEX_NORMAL。
The pthread_mutex_trylock() function shall be equivalent to pthread_mutex_lock(), except that if the mutex object referenced by mutex
is currently locked (by any thread, including the current thread), the call shall return immediately. If the mutex type is
PTHREAD_MUTEX_RECURSIVE and the mutex is currently owned by the calling thread, the mutex lock count shall be incremented by one and
the pthread_mutex_trylock() function shall immediately return success.
--------pthread_mutex_trylock()函数等同于pthread_mutex_lock()函数,除了下列情况:mutex已经被其他线程或当前线程锁住,pthread_mutex_trylock将立即返回。
如果mutex是PTHREAD_MUTEX_RECURSIVE类型,且mutex被当前线程锁住,mutex锁住次数将马上增加1,且立即返回成功。
The pthread_mutex_unlock() function shall release the mutex object referenced by mutex. The manner in which a mutex is released is
dependent upon the mutex’s type attribute. If there are threads blocked on the mutex object referenced by mutex when
pthread_mutex_unlock() is called, resulting in the mutex becoming available, the scheduling policy shall determine which thread shall
acquire the mutex.
(In the case of PTHREAD_MUTEX_RECURSIVE mutexes, the mutex shall become available when the count reaches zero and the calling thread
no longer has any locks on this mutex.)
--------pthread_mutex_unlock()函数释放mutex对象的锁。释放mutex后的行为取决于mutex类型属性。如果有多个线程正被此mutex对象阻塞,释放此mutex时,mutex可被
获取,调度策略决定哪个线程获取此mutex。(mutex类型为PTHREAD_MUTEX_RECURSIVE时,当锁住次数为0且调用线程不再拥有该mutex时,mutex才变为可用。)
If a signal is delivered to a thread waiting for a mutex, upon return from the signal handler the thread shall resume waiting for the
mutex as if it was not interrupted.
--------如果一个线程在等待一个mutex锁得时候收到了一个signal,那么在从signal handler返回的时候,该线程继续等待该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.
-------成功,pthread_mutex_lock和pthread_mutex_unlock返回0;否则返回一个错误码
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.
-------当一个Mutex对象可以获取时,pthread_mutex_trylock()返回0。其他情况返回一个错误码。
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 inter-
face.
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 mecha-
nism 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_tryun-
lock operation.
--------mutex对象被设计成低级原始的,其他线程同步功能可以在其上构建。所以,mutex的实现必须尽可能的高效,mutex有一些衍生的功能特性。
mutex函数和特定的默认mutex属性配置,被设计成不能妨碍其快速性。
例如,死锁问题是可能的行为,目的是为了避免因此产生额外的消耗。(可以检测死锁的更友好的mutex,可以通过其他的机制来构建。例如,pthread_self()能够用来记录
mutex的拥有者。)诸如此类的扩展特性可以通过特殊的Mutex属性来实现。
FUTURE DIRECTIONS
None.
SEE ALSO
pthread_mutex_destroy() , pthread_mutex_timedlock() , the Base Definitions volume of IEEE Std 1003.1-2001,
COPYRIGHT
Portions of this text are reprinted and reproduced in electronic form from IEEE Std 1003.1, 2003 Edition, Standard for Information
Technology -- Portable Operating System Interface (POSIX), The Open Group Base Specifications Issue 6, Copyright (C) 2001-2003 by the
Institute of Electrical and Electronics Engineers, Inc and The Open Group. In the event of any discrepancy between this version and
the original IEEE and The Open Group Standard, the original IEEE and The Open Group Standard is the referee document. The original
Standard can be obtained online at .
IEEE/The Open Group 2003 PTHREAD_MUTEX_LOCK(P)