线程同步之互斥锁

同步非同时

说道线程的“同”步,“同”总会被人理解成“同时,一起”,我刚开始就是这么认为的。其实不然,这里的同步指的是有序执行。就像“B需要A计算出的结果,所以B等待直到A计算出结果后开始执行,A计算完后退出”这样一种状况。而有序执行,就需要用到互斥锁条件变量

互斥锁

互斥锁(也叫互斥量)是保护数据的一个机制,它确保同一时间只有一个线程访问数据,实现了读写数据的串行化。访问数据前加锁,访问数据后解锁。如果多个线程都可以对一个变量进行读取和修改的话就有必要加互斥锁,否则会引起混乱①。互斥锁是对数据的同步,而条件变量是步骤之间的同步。

操作函数

pthread_mutex_init()
功能:初始化一个互斥锁
函数原型:int pthread_mutex_init(pthread_mutex_t *mutex,const pthread_mutexattr_t *mutexattr);
函数中的参数mutexattr表示互斥锁的属性②,如果为NULL则使用默认属性。

pthread_mutex_lock()
功能:给一个互斥锁加锁
函数原型:int pthread_mutex_lock(pthread_mutex_t *mutex);
如果mutex已经被锁住,当前尝试加锁的现就就会阻塞,直到锁被其他线程释放。当pthread_mutex_lock()返回时,说明互斥锁被当前线程成功加锁。

pthread_mutex_trylock()
功能:测试加锁,如果不成功则立即返回
函数原型:int pthread_mutex_trylock(pthread_mutex_t *mutex);
如果mutex已经被加锁,它将立即返回,返回的错误码③是EBUSY,而不是阻塞等待。

pthread_mutex_unlock()
功能:解锁
函数原型:int pthread_mutex_unlock(pthread_mutex_t *mutex);
用pthread_mutex_unlock解锁时,必须满足两个条件:互斥锁必须是加锁的状态,解锁的这个线程必须是加锁的那个。如果有其他线程在等待互斥锁,等待队列中的第一个线程奖获得互斥锁。

pthread_mutex_destory()
功能:使用完毕之后清除一个互斥锁
函数原型:int pthread_mutex_destory(pthread_mutex_t *mutex);
清除一个互斥锁就是释放它所占用的资源。清除锁时要求当前处于没锁定的状态,若锁处于锁定状态,函数返回EBUSY,该函数成功执行时返回0。

注释

①:以增量操作为例。增量操作可以分为三步:
1从内存中读入寄存器。
2在寄存器中对变量做增量操作。
3把结果写回内存单元。
从变量的角度来看如果A线程执行了1,2然后B线程执行了1然后A线程执行了3那么显然B线程读到的数据是不对的。而在有些情况下写入变量的数据也会和我们预想的不一样。所以我们需要互斥锁让一个线程执行完1,2,3之后再由另一个线程来操作。
②:互斥锁的属性包括普通锁,嵌套锁,检错锁,适应锁等。笔者水平有限,请您自行查阅。
③:错误码是一些定义在errno.h中的宏,通常以字母E开头,后面由一串大写字母或数字组成。EBUSY:资源正在使用,不能共享。

你可能感兴趣的:(线程,Linux编程)