一、互斥量
互斥量从本质上说是一把锁,在访问共享资源前对互斥量进行加锁,在访问完成后释放互斥量上的锁。
互斥量用pthread_mutex_t数据类型表示,在使用互斥变量以前,必须首先对它进行初始化。可以把它设置为常量PTHREAD_MUTEX_INITIALIZER(只对静态分配的互斥量),也可以通过调用pthread_mutex_init函数进行初始化,如果动态地分配互斥量(比如说malloc)那么在释放内存前需要调用pthread_mutex_destroy
#include <pthread.h> int pthread_mutex_init(pthread_mutex_t *restrict mutex,const pthread_mutexattr_t *restrict attr); int pthread_mutex_destroy(pthread_mutex_t *mutex) //返回值:若成功返回0,否则返回错误编号
对互斥量进行加锁,需要调用pthread_mutex_lock,如果互斥量已经上锁,调用线程将阻塞直到互斥量被解锁,对互斥量解锁,需要调用pthread_mutex_unlock
#include <pthread.h> int pthread_mutex_lock(pthread_mutex_t *mutex) int pthread_mutex_trylock(pthread_mutex_t *mutex) int pthread_mutex_unlock(pthread_mutex_t *mutex) //返回值:若成功返回0,否则返回错误编号
如果线程不希望被阻塞,它可以使用pthread_mutex_trylock尝试对互斥量进行加锁,如果调用pthread_mutex_trylock时互斥量处于未锁住状态,那么pthread_mutex_trylock将锁住互斥量,不会出现阻塞并返回0,否则pthread_mutex_trylock就会失败,不能锁住互斥量,而返回EBUSY。
二、避免死锁
1.控制互斥量加锁顺序:总是让多个互斥量以相同的顺序加锁
2.合理安排锁的功能:如果锁的粒度太粗,就会出现很多线程阻塞等待相同的锁;如果锁的粒度太细,那么过多的锁开销会使系统性能受到影响,而且代码变得复杂。
三、读写锁
读写锁可以有三种状态:读模式下加锁状态,写模式下加锁状态,不加锁状态。一次只有一个线程可以占有写模式的读写锁,但是多个线程可以同时占有读模式的读写锁。
读写锁在使用之前必须初始化,在释放它们底层的内存前必须销毁。
#include <pthread.h> int pthread_rwlock_init(pthread_rwlock_t *restrict rwllock,const pthread_rwlockattr_t *restrict attr);; int pthread_rwlock_destroy(pthread_rwlock_t *rwlock);
#include <pthread.h> int pthread_rwlock_rdlock(pthread_rwlock_t *rwlock);//读模式下锁定读写锁 int pthread_rwlock_wrlock(pthread_rwlock_t *rwlock);//写模式下锁定读写锁 int pthread_rwlock_unlock(pthread_rwlock_t *rwlock);//解锁
四、条件变量