内核同步方法-原子操作

本文详细介绍了Linux内核中的原子操作,包括原子整数操作和原子位操作。原子整数操作通过`atomic_t`数据类型实现,常用于计数器,提供了如`atomic_set`、`atomic_add`等内联函数。原子位操作则直接作用于内存地址,通过`<asm/bitops.h>`头文件提供的函数如`set_bit`、`clear_bit`等完成。这些操作在多线程环境下确保了操作的不可中断性,避免了锁的使用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

原子操作概念:

      可以保证指令以原子的方式执行---执行的过程不被打断,内核共提供了两组原子操作接口分别是

      1、一组针对整数进行操作

      2、一组针对单独的位进行操作

    下面详述之

     一、原子整数操作

     数据类型:atomic_t 这里之所以引入新的数据类型的原因有2,第一个,让原子整数操作函数只接受atomic_t的数据类型,可以确保该数据类型不会误传给其他非原子整数操作函数,第二个,防止被编辑器优化。

    头文件: <asm/atomic.h>

    范例:

    atomic_t v;                                                  //定义v             

    atomic_t u = ATOMIC_INIT(0);                    //定义u 并把它初始化为 0

    操作:

    atomic_set(&v,4);                                       //v=4             (原子地)

    atomic_add(2,&v);                                      //v = v + 2 = 6 (原子地)

    atomic_inc(&v);                                          //v = v + 1=7 (原子地)

     如果需要将atomic_t转化为int,用atomic_read()完成:

     printk("%d",atomic_read(&v));                                   //打印出7

     应用举例:原子整数操作最常见的用途就是实现计数器。使用一个复杂的锁机制来保护一个单纯的计数器是很笨拙的。

     注意点1:使用atomic_t型的数据类型,只能将该数据当作24位来用。原因是因为在SPARC的体系结构上,这种体系结构是缺乏指令级的支持,他的解决办法,是在32位的int类型的低8位嵌入一个锁。

     注意点2:原子操作通常是内联函数,往往是通过内嵌汇编指令来实现的。

     拓展:

      二、原子位操作

     数据类型:无特殊的数据类型 (int)由位操作函数是普通的内存地址进行操作的,所以不像原子整型对应atomic_t,这里没有特殊的数据类型,相反,只要指针指向了任何你希望的数据,你就可以对它进行操作。

     头文件: <asm/bitops.h>

    范例:

    unsigned long word = 0;

    set_bit(0,&word);

    set_bit(1,&word);

    

     补充:

     内核还提供了一组与上述操作对应的非原子位函数,其名字前缀多两个下划线。内核还提供了两个例程用来从指定的地址开始搜索第一个被设置(或未被设置)的位:
int find_first_bit(unsigned long *addr,unsigned int size)
int find_first_zero_bit(unsigned long *addr,unsigned int size)

 

 

    

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值