linux内核原子操作使用简介

驱动开发住常见的一个问题:就是一个驱动可以被多个进程同时打开,使用,这样会导致驱动功能混乱。

./app & ./app & ./app   可以同时打开这个设备,可通过文件描述符调用驱动的其他接口操作这个设备。

如果想只一个进程使用这个设备,只需要在open接口函数做打开判断。

示例:
static int  open_flag = 0;
//打开设备时候执行的程序
static int  chrdev_open(struct inode *pinode, struct file *pfile)
{
   //打开判断
    if(open_flag)
        return -EBUSY;
    open_flag = 1;   //设置    设备已经被打开的标志
     
    printk(KERN_EMERG "line:%d,%s is call\n", __LINE__, __FUNCTION__);

    return 0;
}

//关闭设备时执行的程序
static int chrdev_release(struct inode *pinode, struct file *pfile)
{
    open_flag = 0;   //设置    设备已经被打开的标志
    printk(KERN_EMERG "line:%d,%s is call\n", __LINE__, __FUNCTION__);
    return 0;
}

以上的效果实现,但是不安全。
分析:
open_flag = 1;   这条语句编译汇编 最少得3条。 只需要执行时候没有一次完成,中途被其他进程打开,刚刚这个进程又调用open打开这个设备。这样,新进程也可以打开成功。

怎么样才可以安全做一次性执行完成这三个步骤?

关系统中断;    -->关中断后不会任务调度情况,这样就是安全。
open_flag = 1;     
开系统中断;    -->重新恢复系统调度

示例:
unsigned long flags;
raw_local_irq_save(flags);     //关中断
open_flag = 1;                       //设置    设备已经被打开的标志
raw_local_irq_restore(flags); //开中断

Linux内核已经提供相关的一些,很方便实现这样的效果。原子操作,信号量,互斥信号量,自旋锁。

原子操作:

1.概念:

原子,是最小的可以独立存在的物质单元,是不可分割。把一个完整的,不可中断的操作过程称为原子操作。Linux系统中的原子本质就是对一个Int类型变量进行操作,但是,它整个操作操作进行控制,保证这个过程是一次性完成。

2. 数据结构  

Types.h (include\linux)

typedef struct {
	volatile int counter;
} atomic_t;

本质 就是一个int类型变量,可以这个机制很简单,内核只提供对这个变量的+,-,读,赋值操作相关的接口。volatile 修饰字段告诉 gcc 不要对该类型的数据做优化处理,对它的访问都是对内存的访问,而不是对寄存器的访问。
 

3. 相关的API

Atomic.h (include\linux)
Atomic.h (include\asm-generic)

ATOMIC_INIT(v);

宏原型 #define ATOMIC_INIT(i) { (i) }
  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值