linux 原子变量
有时, 一个共享资源是一个简单的整数值. 假设你的驱动维护一个共享变量 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]变量加减赋值以及将String转int
- 在linux 安装oracle10g时遇到的问题
- linux查看及修改文件权限以及相关
- [systemd]Linux系统启动之systemd
- linux so库路径设置( LD_LIBRARY_PATH)
- 【学习总结】快速上手Linux玩转典型应用-第2章-linux简介
- linux命令中的字符串中间增加指令,例如路径中增加日期变量,实时获取当前的日期
- Linux Shell脚本自动化编程实战-shell变量(一)
- Linux系统下查看已经登录用户并踢出的方法
- Linux基础之linux服务器服务器间拷贝文件
- Linux 中文乱码问题
- linux驱动开发重点关注内容--摘自《嵌入式Linux驱动模板精讲与项目实践》
- 【Linux 内核】Linux 内核源码根目录下的文件 ( .clang-format | COPYING | CREDITS | Kbuild | Kconfig | MAINTAINERS )
- 【Linux 内核】编译 Linux 内核 ② ( 解压内核源码 | 查询当前 Linux 内核版本号 | 进入并查看 linux 内核源码目录 )
- L70.linux命令每日一练 -- 第十章 Linux网络管理命令 -- nc和ssh
- L66.linux命令每日一练 -- 第十章 Linux网络管理命令 -- arp和ip
- L65.linux命令每日一练 -- 第十章 Linux网络管理命令 -- ifdown和route
- L64.linux命令每日一练 -- 第十章 Linux网络管理命令 -- ifconfig和ifup
- L62.linux命令每日一练 -- 第九章 Linux进程管理命令 -- strace和ltrace
- L52.linux命令每日一练 -- 第八章 Linux磁盘与文件系统管理命令 -- resize2fs和fsck
- L51.linux命令每日一练 -- 第八章 Linux磁盘与文件系统管理命令 -- mkfs和dumpe2fs
- L49.linux命令每日一练 -- 第八章 Linux磁盘与文件系统管理命令 -- fdisk和partprobe
- L42.linux命令每日一练 -- 第七章 Linux用户管理及用户信息查询命令 -- groupdel和passwd
- L3.linux命令每日一练 -- 第一章 Linux命令行简介
- Linux基础之shell变量
- Linux 操作系统基础知识总结
- Linux useradd -M -s
- ZYNQ - 嵌入式Linux开发 -08- linux应用程序开发
- Linux centos7 一键离线安装OpenStack单实例脚本(queens版本,修订版本)
- 云原生之使用Docker部署Linux命令大全搜索工具
- Linux好用命令之gzip保留原文件解压缩
- 安装VMware虚拟机操作到Linux联网时显示线缆被拔出解决方法(以太网不可用)
- Ubuntu 安装Samba(Linux与Windows共享文件)