标签:
转载 |
分类: linux程序 |
很不错~
原文地址:PTHREAD_MUTEX(3)作者:YinFeeling
PTHREAD_MUTEX(3)
名称
pthread_mutex_init, pthread_mutex_lock, pthread_mutex_trylock,
pthread_mutex_unlock, pthread_mutex_destroy – 互斥体操作
大纲
#include
pthread_mutex_t fastmutex = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_t recmutex = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
pthread_mutex_t errchkmutex = PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP;
int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutex_attr_t *mutexattr);
int pthread_mutex_lock(pthread_mutex_t *mutex);
int pthread_mutex_trylock(pthread_mutex_t *mutex);
int pthread_mutex_unlock(pthread_mutex_t *mutex);
int pthread_mutex_destroy(pthread_mutex_t *mutex);
描述
mutex是一种互斥体设备,在并发,实现临界和监控时对保护数据很有帮助。
互斥体有两种可能的状态:未锁定(不被任何线程拥有)和锁定(被一个线程拥有)。一个互斥体在任何情况下都不可能被两个线程同时拥有。当一个线程试图去锁定一个已经被其它线程锁定的互斥体时,它会一直等待直到拥有锁的线程先解除锁定。
pthread_mutex_init函数依据mutexattr指定的属性初始化mutex指向的互斥设备。如果mutexattr为NULL,使用默认属性。
LinuxThread只实现了一种互斥属性:mutex类型,值为’fast’,’recursive’或’error checking’之一。mutex类型取决于拥有它的线程能否将它再锁定一次。默认的类型是’fast’。关于mutex的属性请查看pthread_mutexattr_init(3)获取更多的信息。
pthread_mutex_t变量可以静态的进行初始化,使用PTHREAD_MUTEX_INITIALIZER(fast mutex),或PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP( recursive mutex), 或PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP(error checking mutex)。
pthread_mutex_lock函数锁定给定的互斥体。如果互斥体当前是未锁定状态,锁定它并且会属于调用线程,然后立刻返回。如果互斥体已经被其它线程锁定,调用线程将被挂起,直到互斥体被释放。
如果互斥体已经被调用者锁定,pthread_mutex_lock函数的行为取决于互斥体的类型。如果互斥体的类型是fast,调用线程将被挂起直到互斥体被释放,这会引起调用线程的死锁。如果互斥体的类型是’error checking’,pthread_mutex_lock立即返回EDEAKLK。如果互斥体是recursive类型的,pthread_mutex_lock会调用成功,并立即返回,它将记录下调用者锁定互斥体的次数。要释放互斥体也必须调用相同次数的pthread_mutex_unlock函数。
pthread_mutex_trylock函数的行为和pthread_mutex_lock几乎一样,只是如果互斥体已经锁定,它不会挂起调用线程,而是立即返回一个EBUSY的出错码。
pthread_mutex_unlock释放一次指定的互斥体。它假设给定的互斥体是锁定的,并且被调用者拥有。如果是fast类型的互斥体,pthread_mutex_unlock会将互斥体置为未锁定状态,如果是recursive类型,会在锁定的次数上减一,只有这个数为0时,互斥体才真正的被释放。
对于error checking类型的互斥体,pthread_mutex_unlock只在运行时检查是否是当前线程拥有互斥体,以及是不是当前线程在调用pthread_mutex_unlock函数。如果不是这些情况的一种,互斥体的状态不会改变,会返回一个出错码。’fast’和’recursive’不执行这样的检查,因此也就允许另一个线程释放这个线程的锁定。这不是可移植的行为,因此也不可靠。
pthread_mutex_destroy销毁一个互斥体,释放它可能持有的资源。此时的互斥体必须是未锁定的。在LinuxThread的实现当中,互斥体不占用任何资源,因此pthread_mutex_destroy除了检查互斥体是否处于锁定状态外也没作什么。
取消
没有任何一个互斥体函数是取消点,甚至是pthread_mutex_lock也不行,不管它可能会被挂起多长时间。这样,取消点的状态就是可预见的,就允许线程在停止执行之前来释放一个需要被释放的互斥体。因此,使用延时取消的线程永远不要在互斥体中使用延时操作。
同步信号的安全性
互斥体函数对同步信号是不安全的。这句话的意思是说,它们不应该被信号处理函数调用。特别的,如果它们被信号处理函数调用可能会导致死锁。
返回值
pthread_mutex_init函数总是返回0.其它的函数在调用成功的时候返回0,出错的时候返回非零的出错码。
出错码
pthread_mutex_lock函数在出错时返回下面的代码:
EINVAL:互斥体没有被正确的进行初始化。
EDEAKLK:互斥体已经被调用者锁定。(仅针对error checking类型。)
pthread_mutex_trylock函数在出错时返回下面的代码:
EBUSY:互斥体不能使用,因为它已经被锁定。
EINVAL:未被正确初始化。
pthread_mutex_unlock函数在出错时返回下面的代码:
EINVAL:未被正确初始化。
EPERM:调用者不拥有互斥体(只针对error checking类型)。
pthread_mutex_destroy函数在出错时返回下面的代码:
EBUSY:互斥体已经被锁定。
作者
Xavier Leroy
参见
pthread_mutexattr_init(3), pthread_mutexattr_setkind_np(3),
pthread_cancel(3).
示例:
全局共享变量可以像下面一样使用互斥体保护起来:
int x;
pthread_mutex_t mut = PTHREAD_MUTEX_INITIALIZER;
所有访问和修改x的操作都应该用pthread_mutex_lock和pthread_mutex_unlock包装起来:
pthread_mutex_lock(&mut);
pthread_mutex_unlock(&mut);
名称
pthread_mutex_init, pthread_mutex_lock, pthread_mutex_trylock,
pthread_mutex_unlock, pthread_mutex_destroy – 互斥体操作
大纲
#include
pthread_mutex_t fastmutex = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_t recmutex = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
pthread_mutex_t errchkmutex = PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP;
int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutex_attr_t *mutexattr);
int pthread_mutex_lock(pthread_mutex_t *mutex);
int pthread_mutex_trylock(pthread_mutex_t *mutex);
int pthread_mutex_unlock(pthread_mutex_t *mutex);
int pthread_mutex_destroy(pthread_mutex_t *mutex);
描述
mutex是一种互斥体设备,在并发,实现临界和监控时对保护数据很有帮助。
互斥体有两种可能的状态:未锁定(不被任何线程拥有)和锁定(被一个线程拥有)。一个互斥体在任何情况下都不可能被两个线程同时拥有。当一个线程试图去锁定一个已经被其它线程锁定的互斥体时,它会一直等待直到拥有锁的线程先解除锁定。
pthread_mutex_init函数依据mutexattr指定的属性初始化mutex指向的互斥设备。如果mutexattr为NULL,使用默认属性。
LinuxThread只实现了一种互斥属性:mutex类型,值为’fast’,’recursive’或’error checking’之一。mutex类型取决于拥有它的线程能否将它再锁定一次。默认的类型是’fast’。关于mutex的属性请查看pthread_mutexattr_init(3)获取更多的信息。
pthread_mutex_t变量可以静态的进行初始化,使用PTHREAD_MUTEX_INITIALIZER(fast mutex),或PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP( recursive mutex), 或PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP(error checking mutex)。
pthread_mutex_lock函数锁定给定的互斥体。如果互斥体当前是未锁定状态,锁定它并且会属于调用线程,然后立刻返回。如果互斥体已经被其它线程锁定,调用线程将被挂起,直到互斥体被释放。
如果互斥体已经被调用者锁定,pthread_mutex_lock函数的行为取决于互斥体的类型。如果互斥体的类型是fast,调用线程将被挂起直到互斥体被释放,这会引起调用线程的死锁。如果互斥体的类型是’error checking’,pthread_mutex_lock立即返回EDEAKLK。如果互斥体是recursive类型的,pthread_mutex_lock会调用成功,并立即返回,它将记录下调用者锁定互斥体的次数。要释放互斥体也必须调用相同次数的pthread_mutex_unlock函数。
pthread_mutex_trylock函数的行为和pthread_mutex_lock几乎一样,只是如果互斥体已经锁定,它不会挂起调用线程,而是立即返回一个EBUSY的出错码。
pthread_mutex_unlock释放一次指定的互斥体。它假设给定的互斥体是锁定的,并且被调用者拥有。如果是fast类型的互斥体,pthread_mutex_unlock会将互斥体置为未锁定状态,如果是recursive类型,会在锁定的次数上减一,只有这个数为0时,互斥体才真正的被释放。
对于error checking类型的互斥体,pthread_mutex_unlock只在运行时检查是否是当前线程拥有互斥体,以及是不是当前线程在调用pthread_mutex_unlock函数。如果不是这些情况的一种,互斥体的状态不会改变,会返回一个出错码。’fast’和’recursive’不执行这样的检查,因此也就允许另一个线程释放这个线程的锁定。这不是可移植的行为,因此也不可靠。
pthread_mutex_destroy销毁一个互斥体,释放它可能持有的资源。此时的互斥体必须是未锁定的。在LinuxThread的实现当中,互斥体不占用任何资源,因此pthread_mutex_destroy除了检查互斥体是否处于锁定状态外也没作什么。
取消
没有任何一个互斥体函数是取消点,甚至是pthread_mutex_lock也不行,不管它可能会被挂起多长时间。这样,取消点的状态就是可预见的,就允许线程在停止执行之前来释放一个需要被释放的互斥体。因此,使用延时取消的线程永远不要在互斥体中使用延时操作。
同步信号的安全性
互斥体函数对同步信号是不安全的。这句话的意思是说,它们不应该被信号处理函数调用。特别的,如果它们被信号处理函数调用可能会导致死锁。
返回值
pthread_mutex_init函数总是返回0.其它的函数在调用成功的时候返回0,出错的时候返回非零的出错码。
出错码
pthread_mutex_lock函数在出错时返回下面的代码:
EINVAL:互斥体没有被正确的进行初始化。
EDEAKLK:互斥体已经被调用者锁定。(仅针对error checking类型。)
pthread_mutex_trylock函数在出错时返回下面的代码:
EBUSY:互斥体不能使用,因为它已经被锁定。
EINVAL:未被正确初始化。
pthread_mutex_unlock函数在出错时返回下面的代码:
EINVAL:未被正确初始化。
EPERM:调用者不拥有互斥体(只针对error checking类型)。
pthread_mutex_destroy函数在出错时返回下面的代码:
EBUSY:互斥体已经被锁定。
作者
Xavier Leroy
参见
pthread_mutexattr_init(3), pthread_mutexattr_setkind_np(3),
pthread_cancel(3).
示例:
全局共享变量可以像下面一样使用互斥体保护起来:
int x;
pthread_mutex_t mut = PTHREAD_MUTEX_INITIALIZER;
所有访问和修改x的操作都应该用pthread_mutex_lock和pthread_mutex_unlock包装起来:
pthread_mutex_lock(&mut);
pthread_mutex_unlock(&mut);