Linux mutex相关知识

来源:互联网 发布:购买淘宝网店铺 编辑:程序博客网 时间:2024/04/30 23:01

         互斥锁(Mutex)是一种简单的通过加锁的方法来控制对共享资源的存取,一般用于解决线程间资源访问的唯一性问题.互斥锁其实很简单,它只有两种状态:上锁和解锁.在同一时刻只能有一个线程掌握某个互斥的锁,拥有上锁状态的线程能够对共享资源进行操作.若其他线程希望对一个已经上了锁的互斥锁上锁,则该线程就会挂起,直到上锁的线程释放掉互斥锁为止。

    互斥锁的使用过程中,主要有以下函数:

(1):pthread_mutex_init(pthread_mutex_t * mutex,const pthread_mutexattr_t *attr);

   初始化锁变量mutex。attr为锁属性,NULL值为默认属性。
(2):pthread_mutex_lock(pthread_mutex_t *mutex);加锁。对于一个已上锁的互斥锁若调用pthread_mutex_lock()函数再次上锁,将使调用线程阻塞,直到互斥锁被解锁。调用成功返回0,失败返回-1.
(3):pthread_mutex_trylock(pthread_mutex_t *mutex);加锁。对于一个已上锁的互斥锁,若调用pthread_mutex_trylock()函数再次加锁,将返回错误EBUSY(已加锁错误),因而不会发生阻塞。对于未上锁的情况,该函数将对互斥锁加锁。调用成功返回0,失败返回-1。
(4):pthread_mutex_unlock(pthread_mutex_t *mutex);释放锁
(5):pthread_mutex_destroy(pthread_mutex_t *mutex);使用完后释放。可以释放锁占用的资源,前提是当前处于未被锁的状态。

    锁操作包括pthread_mutex_lock()、pthread_mutex_unlock()和pthread_mutex_trylock()不论哪种类型的锁都不可能被两个不同的线程同时得到,而必须等待解锁。对于普通锁和适应锁类型,解锁者可以是同进程内任何线程;而检错锁和嵌套锁则必须由加锁者解锁才有效,否则返回EPERM(Operation not permitted)。在同一进程中的线程,如果加锁后没有解锁,则任何其他线程都无法再获得锁。

1.互斥锁的创建

互斥锁的创建有两种方法,一种是静态创建,一种是动态创建。

(1)静态创建:

POSIX定义了一个一个宏PTHREAD_MUTEX_INITIALIZER来静态初始化互斥锁,方法如下:

pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;

(2)动态创建:

动态方式是采用pthread_mutex_init()函数来初始化互斥锁,函数定义如下:

int pthread_mutex_init(pthread_mutex_t *mutex,const pthread_mutexattr_t *mutexattr),其中mutexattr用于指定互斥锁属性,如果为NULL则使用缺省属性。关于mutexattr的取值见下文。

2.互斥锁的属性:

互斥锁的属性在创建锁的时候指定,互斥锁属性的取值有以下几个:

PTHREAD_MUTEX_TIMED_NP,这是缺省值也就是普通锁。当一个线程加锁后,其余请求所的线程将形成一个等待队列,并在解锁后按优先级获得锁。这种锁策略保证了资源分配的公平性。

PTHREAD_MUTEX_RECURSIVE_NP,嵌套锁。允许同一个线程对同一个锁成功获得多次,并通过unlock解锁。如果是不同线程请求,则在加锁线程解锁时重新竞争。

PTHREAD_MUTEX_ERRORCHECK_NP,检错锁。如果同一个线程请求同一个锁,则返回EDEADLK(描述:将出现死锁,如一个线程等待其本身或者线程A和线程B互相等待),否则与PTHREAD_MUTEX_TIMED_NP类型动作相同。这样就保证当不允许多次加锁时不会出现最简单情况下的死锁。

PTHREAD_MUTEX_ADAPTIVE_NP,适应锁。动作最简单的锁类型,仅等待解锁后重新竞争。

设置和获取锁类型的函数为:

pthread_mutexattr_settype(pthread_mutexattr_t *attr,int type);

pthread_mutexattr_gettype(pthread_mutexattr_t *attr,int *type);

0 0
原创粉丝点击