一、自旋锁和互斥锁的异同
1.1、自旋锁
- [1]当一个线程在获取锁的时候,如果其它线程已经获取了锁,那么该线程会不停的尝试去获取锁,在此期间它会占用cpu的资源;
- [2]使用自旋锁不会导致进程和线程的切换,所以适用于时间很短的情况。
- [3]自旋锁可以在多进程中使用,通过pthread_spin_init的第二个参数设置。
2.2、互斥锁
- [1] 当一个线程在获取锁的时候,如果其它线程已经获取了锁,那么该线程会不停的尝试去获取锁,在此期间它会释放cpu的资源(进入休眠);
- [2]当线程A试图获取互斥锁,但是该互斥锁已经被线程B占用时,线程A会让出cpu的使用权,进行线程切换,让其它高优先级的任务运行。
- [3]自旋锁不能用于递归函数,否则容易造成死锁;
二、互斥锁和自旋锁的异同点
- 相同点:
互斥锁和自旋锁都可以解决操作系统在访问共享资源时产生的竞争问题,从而保证多个线程同一时刻只能有一个线程访问共享资源; - 不同点:
互斥锁在试用期间不会占用cpu资源,而是会处于休眠状态,把cpu的使用权交给其它线程,即可以进行上下文的切换;自旋锁在使用期间会处于忙等待状态,不停的尝试去获取锁,在此期间它会一直占用cpu的使用权,不能进行上下文切换,自旋锁的效率高于互斥锁;
三、互斥锁相关函数
1.pthread_mutex_init互斥锁初始化
函数原型:int pthread_mutex_init(pthread_mutex_t *restrict mutex, const pthread_mutexattr_t *restrict attr);
函数功能:初始化互斥锁
函数参数:mutex 互斥锁句柄
attr 互斥锁属性
返回值:成功返回0,失败返回对应的错误码
说明:初始化一个已经初始化过的互斥锁会导致未知的问题;
mutex如果是静态分配的,可以用PTHREAD_MUTEX_INITIALIZER进行初始化,如果是动态分配的,需要用attr声明其属性;
2.pthread_mutex_destroy销毁互斥锁
函数原型: int pthread_mutex_destroy(pthread_mutex_t *mutex);
函数功能:初始化互斥锁
函数参数:mutex 互斥锁句柄
返回值:成功返回0,失败返回对应的错误码
说明:销毁一个未释放的互斥锁会导致未知的问题;
3.pthread_mutex_lock获取互斥锁
函数原型: int pthread_mutex_lock(pthread_mutex_t *mutex);
函数功能:获取一个互斥锁
函数参数:mutex 互斥锁句柄
返回值:成功返回0,失败返回对应的错误码
说明:销毁一个未释放的互斥锁会导致未知的问题;
4.pthread_mutex_timedlock获取互斥锁并设置超时
函数原型: int pthread_mutex_timedlock(pthread_mutex_t *restrict mutex, const struct timespec *restrict abs_timeout);
函数功能:获取互斥锁,如果这个互斥锁被别的线程锁定,那么超过abs_timeout指定的时间自动退出
返回值:成功返回0,如果锁被其它线程锁定,返回EBUSY
5.pthread_mutex_trylock非阻塞获取锁
函数原型: int pthread_mutex_trylock(pthread_mutex_t *mutex);
函数功能:以非阻塞的方式获取互斥锁
返回值:成功返回0,如果锁被其它线程锁定,返回EBUSY
四、自旋锁相关函数
1.pthread_spin_init初始化
函数原型:int pthread_spin_init(pthread_spinlock_t *lock, int pshared);
函数参数:lock 自旋锁句柄
pshared PTHREAD_PROCESS_SHARED表示自旋锁允许多进程使用,PTHREAD_PROCESS_PRIVATE只允许同一进程下的多个线程使用
2.pthread_spin_lock获取锁,阻塞方式
函数原型:int pthread_spin_lock(pthread_spinlock_t *lock);
3.pthread_spin_unlock释放锁
函数原型: int pthread_spin_unlock(pthread_spinlock_t *lock);
4.pthread_spin_trylock非阻塞方式
函数原型: int pthread_spin_trylock(pthread_spinlock_t *lock);