【讯为Linux驱动开发】6.自旋锁spinlock

【自旋锁】

线程A获取自旋锁后,B假如想获取自旋锁则只能原地等待,仍占用CPU不会休眠,直到获取自旋锁为止。

【函数】

DEFINE SÃINLOCK(spinlock t lock)   定义并初始化一个变量
int spin lock init(spinlock t*lock)   初始化自旋锁
void spin lock(spinlock t *lock)    获取自旋锁。也叫做加锁
void spin_unlock(spinlock t *lock)    释放自旋锁,也叫做解锁
int spin trylock(spinlock t *lock)    尝试获取自旋锁,如果没有获取到就返回0
int spin is locked(spinlock t *lock)   检查自旋锁是否被获取,如果没有被获取就返回非0,否则返回0

【如何使用】

  1. 访问临界资源时首先申请自旋锁
  2. 获取自旋锁后进入临界区,获取不到就等待
  3. 退出临界区释放自旋锁 

【临界区】

【注意事项】 

  1. 原地等待消耗CPU。临界区代码一定不能多。
  2. 临界区中不可以调用会导致进程休眠的函数,否则可能死锁
  3. 一般用于多核CPU

【实验】

/* 定义一个自旋锁 */
static spinlock_t my_spinlock;
static flag = 1;  //标志位模拟驱动有没有被用到

static int cdev_open(struct inode *inode, struct file *filp)
{
    spin_lock(my_spinlock);  //加锁
    if(flag != 1){
        spin_unlock(my_spinlock); 
        return -EBUSY;
    }
    flag = 0;
    spin_unlock(my_spinlock);  //解锁
    
    file->private_data = &dev1; //指向设备结构体
    return 0;
}


static int cdev_release(struct inode *inode, struct file *filp)
{
    spin_lock(my_spinlock);  //加锁
    flag = 1;
    spin_unlock(my_spinlock);  //解锁      
}

【验证】

int main(int argc, char *argv[])
{
   int fd1;
   char buf1[32] = "ni hao test1!";
   
   fd1 = open("/dev/test1", HELLO);  /* 打开设备节点1 */   
   sleep(5);  /* 延时5秒,为了实验效果*/
   close(fd1);
  
   return 0;  
}

【实验结果】

A打开驱动程序,假设执行到FLAG = 0,此时又有B要使用驱动,那么Flag = 0意味着A正在使用驱动,同时Flag =0 使得flag !=1所以B进不去驱动,只能报错。

当等A使用驱动完毕,触发release函数,flag被置为1,才意味着其他程序可以使用驱动了。

  • 8
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值