pthread_mutex_init:
一、定义方式:
1、有两种定义方式:
a.静态定义:pthread_mutex_t mutex=PTHREAD_MUTEX_INITIALIZER;
b.动态定义:先定义变量:pthread_mutex_t mutex;,然后调用int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *mutexattr) 函数进行初始化,通常,互斥锁属性mutexattr为NULL,表示使用默认的属性,即:快速互斥锁。
-------返回值: 成功则返回0, 出错则返回错误编号
二、销毁方法:
int pthread_mutex_destroy(pthread_mutex_t *mutex) 用于注销一个互斥锁
:
销毁一个互斥锁即意味着释放它所占用的资源,且要求锁当前处于开放状态。由于在Linux
中,互斥锁并不占用任何资源,因此LinuxThreads
中的pthread_mutex_destroy()
除了检查锁状态以外(锁定状态则返回EBUSY
)没有其他动作。
三、互斥锁属性:
a.缺省值(普通锁):PTHREAD_MUTEX_TIMED_NP 当一个线程加锁以后,其余请求锁的线程将形成一个等待队列,并在解锁后按优先级获得锁。这种锁策略保证了资源分配的公平性。
-----解锁:可以是同进程内任何线程
b.嵌套锁:PTHREAD_MUTEX_RECURSIVE_NP
允许同一个线程对同一个锁成功获得多次,并通过多次unlock
解锁。如果是不同线程请求,则在加锁线程解锁时重新竞争。
-----解锁:必须由加锁者解锁
c.检错锁:PTHREAD_MUTEX_ERRORCHECK_NP
如果同一个线程请求同一个锁,则返回EDEADLK
,否则与PTHREAD_MUTEX_TIMED_NP
类型动作相同。这样就保证当不允许多次加锁时不会出现最简单情况下的死锁
-----解锁:
必须由加锁者解锁才有效,否则返回EPERM
d.适应锁:PTHREAD_MUTEX_ADAPTIVE_NP 最简单的锁类型,仅等待解锁后重新竞争
------解锁:可以是同进程内任何线程
四、上锁 与 解锁:
a.上锁:
方法一:int pthread_mutex_lock(pthread_mutex_t *mutex);返回值: 成功则返回0, 出错则返回错误编号。如果互斥量已经上了锁, 调用线程会阻塞, 直到互斥量被解锁.
方法二:pthread_mutex_trylock(pthread_mutex_t *mutex);返回值: 成功则返回0, 出错则返回错误编号.非阻塞调用模式, 也就是说, 如果互斥量没被锁住, trylock函数将把互斥量加锁, 并获得对共享资源的访问权限; 如果互斥量被锁住了, trylock函数将不会阻塞等待而直接返回EBUSY, 表示共享资源处于忙状态.
b.解锁:int pthread_mutex_unlock(pthread_mutex_t *mutex);返回值: 成功则返回0, 出错则返回错误编号.
五、死锁:
a.出现的环境:发生在有多个依赖锁存在时, 会在一个线程试图以与另一个线程相反顺序锁住互斥量时发生
b.避免方法:
对共享资源操作前一定要获得锁;完成操作以后一定要释放锁;尽量短时间地占用锁;如果有多锁, 如获得顺序是ABC连环扣, 释放顺序也应该是ABC;线程错误返回时应该释放它所获得的锁.
注意:pthread_mutex_trylock()
与pthread_mutex_lock()
类似,但是在锁已经被占据时返回EBUSY
而不是挂起等待