原子操作

原子操作

原子的引入

在上篇文章并发与竞争中,由于多线程对于共享变量的访问而引入的问题,不符合程序的期望。

为了规避这个问题,引入原子操作,对共享变量不能被打断。

原子操作有两种:原子变量,原子位。

原子变量内核操作

原子变量的内核文件:include/linux/types.h

图 1 原子变量数据类型

对于该变量的具体操作函数:(v是atomic类型的指针)

函数名

作用

atomic_read(v)

读出原子变量的值,即v->counter

atomic_set(v,i)

设置原子变量的值,即v->counter = i

atomic_inc(v)

v->counter++

atomic_dec(v)

v->counter--

atomic_add(i,v)

v->counter += i

atomic_sub(i,v)

v->counter -= i

atomic_inc_and_test(v)

先加1,再判断新值是否等于0;等于0的话,返回值为1

atomic_dec_and_test(v)

先减1,再判断新值是否等于0;等于0的话,返回值为1

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

疑问:

为什么原子操作为什么可以起作用?原子操作为什么可以不被打断?

打断是因为发生任务调度,如果没有任务调度,就不会有竞争与毛线。而任务调度是基于中断,如果我们把中断关闭,那就不会参数任务调度,进而不会打断。

所以在执行原子操作,必然有对中断的操作。执行之前先关中断,执行完成之后,再将中断打开。(单核处理器)

对于多核处理器,关中断与开中断的时间开销过大,不是采用对中断操作这种方式。原子操作对于变量一般分为三步:读出,修改,写入。比如线程A在修改环节被线程B抢占,

线程B执行完之后。线程A获知目前该共享区域有更新。重新读出,修改,写入,达到一样原子操作的效果。

举例使用

对于个文件,只允许一个app上位机软件使用。使用之后,才允许另外一个app访问。

图 2 原子变量举例使用

原子位

原子变量是一个变量概念,而原子位是1bit,其值对应0和1。对一个的实现在内核中留有接口,

文件具体路劲: /arch/arm/include/asm/bitops.h具体的操作函数如下:

函数名

作用

set_bit(nr,p)

设置(*p)的bit nr为1

clear_bit(nr,p)

清除(*p)的bit nr为0

change_bit(nr,p)

改变(*p)的bit nr,从1变为0,或是从0变为1

test_and_set_bit(nr,p)

设置(*p)的bit nr为1,返回该位的老值

test_and_clear_bit(nr,p)

清除(*p)的bit nr为0,返回该位的老值

test_and_change_bit(nr,p)

改变(*p)的bit nr,从1变为0,或是从0变为1;返回该位的老值

posted @ 2022-07-30 19:58  JwChu  阅读(246)  评论(0编辑  收藏  举报