有时, 一个共享资源是一个简单的整数值. 假设你的驱动维护一个共享变量 n_op, 它告 知有多少设备操作目前未完成. 正常地, 即便一个简单的操作例如:

n_op++;

可能需要加锁. 某些处理器可能以原子的方式进行那种递减, 但是你不能依赖它. 但是一 个完整的加锁体制对于一个简单的整数值看来过分了. 对于这样的情况, 内核提供了一个 原子整数类型称为 atomic_t, 定义在 <asm/atomic.h>.

一个 atomic_t 持有一个 int 值在所有支持的体系上. 但是, 因为这个类型在某些处理 器上的工作方式, 整个整数范围可能不是都可用的; 因此, 你不应当指望一个 atomic_t

持有多于 24 位. 下面的操作为这个类型定义并且保证对于一个 SMP 计算机的所有处理 器来说是原子的. 操作是非常快的, 因为它们在任何可能时编译成一条单个机器指令.

void atomic_set(atomic_t *v, int i); atomic_t v =
ATOMIC_INIT(0);

设置原子变量 v 为整数值 i. 你也可在编译时使用宏定义 ATOMIC_INIT 初始化原 子值.

int atomic_read(atomic_t *v); 返回 v 的当前值.

void
atomic_add(int i, atomic_t *v);

由 v 指向的原子变量加 i. 返回值是 void, 因为有一个额外的开销来返回新值, 并且大部分时间不需要知道它.

void atomic_sub(int i, atomic_t *v); 从 *v 减去 i.void
atomic_inc(atomic_t *v); void atomic_dec(atomic_t *v);

递增或递减一个原子变量.

int atomic_inc_and_test(atomic_t *v); int
atomic_dec_and_test(atomic_t *v);

int atomic_sub_and_test(int i, atomic_t *v);

进行一个特定的操作并且测试结果; 如果, 在操作后, 原子值是 0, 那么返回值是 真; 否则, 它是假.
注意没有 atomic_add_and_test.

int
atomic_add_negative(int i, atomic_t *v);

加整数变量 i 到 v. 如果结果是负值返回值是真, 否则为假. int
atomic_add_return(int i, atomic_t *v);

int atomic_sub_return(int i, atomic_t *v); int
atomic_inc_return(atomic_t *v);

int atomic_dec_return(atomic_t *v);

就像 atomic_add 和其类似函数, 除了它们返回原子变量的新值给调用者.

如同它们说过的,
atomic_t 数据项必须通过这些函数存取. 如果你传递一个原子项给一 个期望一个整数参数的函数, 你会得到一个编译错误.

你还应当记住, atomic_t 值只在当被置疑的量真正是原子的时候才起作用. 需要多个 atomic_t 变量的操作仍然需要某种其他种类的加锁. 考虑一下下面的代码:

atomic_sub(amount, &first_atomic);
atomic_add(amount, &second_atomic);

从第一个原子值中减去
amount, 但是还没有加到第二个时, 存在一段时间. 如果事情的
这个状态可能产生麻烦给可能在这 2 个操作之间运行的代码, 某种加锁必须采用.

linux 原子变量的更多相关文章

  1. linux内核原子变量与原子位操作API

    原子变量: arch/arm/include/asm/atomic.h 定义并初始化 atomic_t v = ATOMIC_INIT(0); 写 void atomic_set(atomic_t * ...

  2. 【转】linux 原子整数操作详解

    原文网址:http://blog.csdn.net/hunanchenxingyu/article/details/8994379 printk(“%d\n”,atomic_read(&v)) ...

  3. 理解 Linux 条件变量

    理解 Linux 条件变量 1 简介 当多个线程之间因为存在某种依赖关系,导致只有当某个条件存在时,才可以执行某个线程,此时条件变量(pthread_cond_t)可以派上用场.比如: 例1: 当系统 ...

  4. 多线程同步工具——CAS原子变量

    这是我参考的一篇文章<基于CAS的乐观锁实现>,讲述的是一种需要CPU支持的执行技术CAS(Compare and Swap). 首先理解什么是原子性操作,意思是不能再拆分的操作,例如改写 ...

  5. Java并发之原子变量和原子引用与volatile

    我们知道在并发编程中,多个线程共享某个变量或者对象时,必须要进行同步.同步的包含两层作用:1)互斥访问(原子性):2)可见性:也就是多个线程对共享的变量互斥地访问,同时线程对共享变量的修改必须对其他线 ...

  6. Linux 环境变量 设置 etc profile

    一.Linux的变量种类 按变量的生存周期来划分,Linux变量可分为两类: 1.永久的:需要修改配置文件,变量永久生效. 2.临时的:使用export命令声明即可,变量在关闭shell时失效. 二. ...

  7. java并发编程学习: 原子变量(CAS)

    先上一段代码: package test; public class Program { public static int i = 0; private static class Next exte ...

  8. 【翻译二十二】java-并发之集合与原子变量

    Concurrent Collections The java.util.concurrent package includes a number of additions to the Java C ...

  9. linux 环境变量设置及查看

    1. 显示环境变量HOME $ echo $HOME /home/redbooks 2. 设置一个新的环境变量hello $ export HELLO="Hello!" $ ech ...

随机推荐

  1. 类似淘宝五星点评 ,Jquery实现代码

    <!--默认五星,根据鼠标点击判断--> <!DOCTYPE html><html lang="en"><head> <met ...

  2. Spring_Aop_(二)

    切面的优先级 @Order(1)注解 指定切面的优先级,值越小优先级越高 @Order(1) @Aspect @Component public class VlidationAspect { @Be ...

  3. 字体图标font-awesome

    其实有一些常见的图标使用字体图标比使用img来得好 Font Awesome 官网:http://fortawesome.github.io/Font-Awesome/ 字体代码:http://for ...

  4. Liunx vi/vim 2

    移动光标的方法 H 光标移动到这个屏幕的最上方那一行的第一个字符 M  光标移动到这个屏幕的中央那一行的第一个字符 L 光标移动到这个屏幕的最下方那一行的第一个字符 G 移动到这个档案的最后一行(常用 ...

  5. 13 -1 BOM和定时器

    一 BOM JavaScript基础分为三个部分: ECMAScript:JavaScript的语法标准.包括变量.表达式.运算符.函数.if语句.for语句等. DOM:文档对象模型,操作网页上的元 ...

  6. Python基础:20类的定制

    类中有一些可自定义的特殊方法,它们中的一些有预定义的默认行为,而其它一些则没有,留到需要的时候去实现.这些特殊方法是Python中用来扩充类的强有力的方式.它们可以实现模拟标准类型和重载操作符等.比如 ...

  7. 注意 Laravel 清除缓存 php artisan cache:clear 的一个坑

    Laravel 的命令 php artisan cache:clear 用来清除各种缓存,如页面,Redis,配置文件等缓存,它会清空 Redis 数据库的全部数据,比如默认使用的 Redis 的 数 ...

  8. oracle避免在索引列上使用IS NULL和IS NOT NULL

    避免在索引中使用任何可以为空的列,ORACLE将无法使用该索引 .对于单列索引,如果列包含空值,索引中将不存在此记录. 对于复合索引,如果每个列都为空,索引中同样不存在此记录. 如果至少有一个列不为空 ...

  9. ngRoute

    ngRoute 模块中包含以下内容, 名称 所属 作用 ngView DIRECTIVE 提供不同路由模板插入的视图层 $routeProvider PROVIDER 提供路由配置 $route SE ...

  10. Redis正确使用的十个技巧

    http://www.jb51.net/article/73376.htm Redis 在当前的技术社区里是非常热门的.从来自 Antirez 一个小小的个人项目到成为内存数据存储行业的标准,Redi ...