锁的种类和应用(部分)

互斥锁

引入了对象互斥锁的概念,来保证共享数据操作的完整性。每个对象都对应于一个可称为" 互斥锁" 的标记,这个标记用来保证在任一时刻,只能有一个线程访问该对象。
互斥锁的操作

1.定义互斥锁变量    pthread_mutex_t
2.初始化互斥锁变量  pthread_mutex_init
3.加锁            pthread_mutex_lock
4.解锁            pthread_mutex_lock
5.销毁互斥锁       pthread_mutex_destory
创建: int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *mutexattr) 其中mutexattr用于指定互斥锁属性,如果为NULL则使用缺省属性。

获取锁:int pthread_mutex_lock(pthread_mutex_t *mutex)  在锁已经被占据时返回挂起等待

销毁:int pthread_mutex_destroy(pthread_mutex_t *mutex)

销毁一个互斥锁即意味着释放它所占用的资源,且要求锁当前处于开放状态。
由于在Linux中,互斥锁并不占用任何资源,pthread_mutex_destroy()除了检查锁状态以外(锁定状态则返回EBUSY)没有其他动作。。

释放锁:int pthread_mutex_unlock(pthread_mutex_t *mutex)

*非阻塞加锁:int pthread_mutex_trylock(pthread_mutex_t *mutex)  在锁已经被占据时返回EBUSY

自旋锁(Spin lock)

自旋锁是专为防止多处理器并发而引入的一种锁,它在内核中大量应用于中断处理等部分
循环判断条件是否满足,反应及时,但是CPU消耗较高,适用于阻塞时间很短的等待
为实现保护共享资源而提出一种锁机制.自旋锁类似于互斥锁,它们都是为了解决对某项资源的互斥使用。无论是互斥锁,还是自旋锁,在任何时刻,最多只能有一个保持者,也就说,在任何时刻最多只能有一个执行单元获得锁。但是两者在调度机制上略有不同。对于互斥锁,如果资源已经被占用,资源申请者只能进入睡眠状态。但是自旋锁不会引起调用者睡眠,如果自旋锁已经被别的执行单元保持,调用者就一直循环在那里看是否该自旋锁的保持者已经释放了锁

自旋锁的操作

1、初始化
   spin_lock_init(x)
   该宏用于初始化自旋锁x。自旋锁在真正使用前必须先初始化。该宏用于动态初始化。

2、加锁
   void spin_lock(spinlock_t *lock);      
   最基本得自旋锁函数,它不失效本地中断。

   void spin_lock_irqsave(spinlock_t *lock, unsigned long flags);
   在获得自旋锁之前禁用硬中断(只在本地处理器上),而先前的中断状态保存在flags中

   void spin_lock_irq(spinlock_t *lock);
   在获得自旋锁之前禁用硬中断(只在本地处理器上),不保存中断状态

   void spin_lock_bh(spinlock_t *lock);
   在获得锁前禁用软中断,保持硬中断打开状态

3、解锁
   spin_unlock(lock);
   该宏释放自旋锁lock,它与spin_trylock或者spin_lock配对使用。如果spin_trylock返回假,表明没有获得自旋锁,因此不必使用spin_unlock(lock)释放。
   
   spin_unlock_bh(lock)
   该宏释放自旋锁lock的同一时候,也使能本地的软中断。它与spin_lock_bh配对使用。
   
   spin_unlock_irqrestore(lock, flags)
   该宏释放自旋锁lock的同一时候,使能本地硬件中断并且恢复标志寄存器的值为变量flags保存的值。它与spin_lock_irqsave配对使用。

   spin_unlock_irq(lock)
   该宏释放自旋锁lock的同一时候,也使能本地中断。它与spin_lock_irq配对使用。

读写锁
读写锁默认读优先
使用读者写者模型 – 写互斥 , 读共享
写的时候, 别人既不能读,也不能写
读的时候可以一起读,但是不能写
若当前已经加写锁,则其他线程加写锁 / 读锁都会被阻塞若当前已经加读锁,则其他线程可以继续加读锁,但是加写锁会阻塞
读写锁的阻塞使用自旋锁实现

读写锁的操作

  1. 初始化和销毁:
#include <pthread.h>

int pthread_rwlock_init(pthread_rwlock_t *restrict rwlock, const pthread_rwlockattr_t *restrict attr);
int pthread_rwlock_destroy(pthread_rwlock_t *rwlock);

成功则返回0, 出错则返回错误编号.
同互斥量以上, 在释放读写锁占用的内存之前, 需要先通过pthread_rwlock_destroy对读写锁进行清理工作, 释放由init分配的资源.
2.读和写:


#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);

成功则返回0, 出错则返回错误编号.
这3个函数分别实现获取读锁, 获取写锁和释放锁的操作. 获取锁的两个函数是阻塞操作, 同样, 非阻塞的函数为:

#include <pthread.h>

int pthread_rwlock_tryrdlock(pthread_rwlock_t *rwlock);
int pthread_rwlock_trywrlock(pthread_rwlock_t *rwlock);

成功则返回0, 出错则返回错误编号.
非阻塞的获取锁操作, 如果可以获取则返回0, 否则返回错误的EBUSY.

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值