安云网 - AnYun.ORG | 专注于网络信息收集、网络数据分享、网络安全研究、网络各种猎奇八卦。
当前位置: 安云网 > 技术关注 > 系统文档 > linux并发控制之原子操作

linux并发控制之原子操作

时间:2016-06-12来源:未知 作者:williamwang2013点击:
原子操作指的是在执行过程中不会被别的代码路径所中断的操作。 分为两类:整型原子操作 和 位原子操作。 特点: 1.任何情况下操作都是原子的。 2.都依赖底层的CPU的原子操作来实现,所以和CPU架构密切相关。 注意: 1.原子操

原子操作指的是在执行过程中不会被别的代码路径所中断的操作。 //本文来自安云网

分为两类:整型原子操作 和 位原子操作。

//copyright AnYun.ORG

特点:

//本文来自安云网

1.任何情况下操作都是原子的。 //ANYUN.ORG

2.都依赖底层的CPU的原子操作来实现,所以和CPU架构密切相关。

//安云网,anyun.org

注意: //安云网咨询系统

    1.原子操作在不同体系架构实现的方法不同,基本采用汇编实现 //内容来自AnYun.ORG

    2.上述的整数原子函数集仅针对32位,内核中关于64位有另一套函数

//内容来自安云网

    3.对于SMP系统,内核还提供了local_t数据类型,实现对单个CPU的整数原子操作,接口函数仅将atomic_替换成local_即可,定义于linux/asm-generic/local.h

//内容来自安云网


//本文来自安云网

一.整型原子操作

//ANYUN.ORG

定义于#include<asm/atomic.h>

//安云网咨询系统

分为 定义,获取,加减,测试,返回。

//本文来自安云网

void atomic_set(atomic_t *v,int i);    //设置原子变量v的值为i

//copyright AnYun.ORG

atomic_t v = ATOMIC_INIT(0);     //定义原子变量v,并初始化为0;

//安云网咨询系统

atomic_read(atomic_t* v);     //返回原子变量v的值;

//copyright AnYun.ORG

void atomic_add(int i, atomic_t* v);     //原子变量v增加i;

//copyright AnYun.ORG

void atomic_sub(int i, atomic_t* v);    

//内容来自安云网

void atomic_inc(atomic_t* v);     //原子变量增加1; //安云网,anyun.org

void atomic_dec(atomic_t* v);     

//ANYUN.ORG

int atomic_inc_and_test(atomic_t* v);        //先自增1,然后测试其值是否为0,若为0,则返回true,否则返回false;

//copyright AnYun.ORG

int atomic_dec_and_test(atomic_t* v);        

//ANYUN.ORG

int atomic_sub_and_test(int i, atomic_t* v);     //先减i,然后测试其值是否为0,若为0,则返回true,否则返回false; //ANYUN.ORG

注意:只有自加,没有加操作 //安云网咨询系统

int atomic_add_return(int i, atomic_t* v);   //v的值加i后返回新的值; //ANYUN.ORG

int atomic_sub_return(int i, atomic_t* v);  

//ANYUN.ORG

int atomic_inc_return(atomic_t* v);     //v的值自增1后返回新的值;

//内容来自AnYun.ORG

int atomic_dec_return(atomic_t* v);     //本文来自安云网

二.位原子操作

//安云网,anyun.org

定义于#include<asm/bitops.h>

//安云网咨询系统

分为 设置,清除,改变,测试 //内容来自AnYun.ORG

void set_bit(int nr, volatile void* addr);        //设置地址addr的第nr位,所谓设置位,就是把位写为1; //copyright AnYun.ORG

void clear_bit(int nr, volatile void* addr);      //清除地址addr的第nr位,所谓清除位,就是把位写为0; //内容来自安云网

void change_bit(int nr, volatile void* addr);     //把地址addr的第nr位反转; //安云网咨询系统

int test_bit(int nr, volatile void* addr);    //返回地址addr的第nr位;

//安云网,anyun.org

int test_and_set_bit(int nr, volatile void* addr);    //测试并设置位;若addr的第nr位非0,则返回true; 若addr的第nr位为0,则返回false;

//ANYUN.ORG

int test_and_clear_bit(int nr, volatile void* addr);    //测试并清除位;

//安云网咨询系统

int test_and_change_bit(int nr, volatile void* addr);    //测试并反转位; //安云网,anyun.org

上述操作等同于先执行test_bit(nr,voidaddr)然后在执行xxx_bit(nr,voidaddr)

//内容来自安云网

举个简单例子: //安云网咨询系统

为了实现设备只能被一个进程打开,从而避免竞态的出现 //内容来自AnYun.ORG

static atomic_t scull_available = ATOMIC_INIT(1);      //init atomic

//安云网咨询系统

在scull_open 函数和scull_close函数中:

//内容来自安云网

int scull_open(struct inode *inode, struct file *filp) //内容来自AnYun.ORG

{ //安云网,anyun.org

    struct scull_dev *dev;         // device information //内容来自安云网

    dev = container_of(inode->i_cdev, struct scull_dev, cdev);

//内容来自AnYun.ORG

    filp->private_data = dev;         // for other methods 

//本文来自安云网

    if(!atomic_dec_and_test(&scull_available)){

//本文来自安云网

        atomic_inc(&scull_available);

//内容来自安云网

        return -EBUSY; //copyright AnYun.ORG

    }

//ANYUN.ORG

    return 0;         // success  //安云网咨询系统

} //内容来自AnYun.ORG

int scull_release(struct inode *inode, struct file *filp) //copyright AnYun.ORG

{

//安云网咨询系统

    atomic_inc(&scull_available); //内容来自安云网

    return 0; //安云网咨询系统

}

//安云网,anyun.org

同样也可以用位原子操作实现

//本文来自安云网


//内容来自安云网

顶一下
(0)
0%
踩一下
(0)
0%
------分隔线----------------------------
发表评论
请自觉遵守互联网相关的政策法规,严禁发布色情、暴力、反动的言论。
评价:
验证码: 点击我更换图片
相关内容
推荐内容
  • The Debian Administrator’s Handbook,

    The Debian Administrator’s Handbook, 这本书是debian的两个开发者写出...

  • 微信4.0发布,加入朋友圈功能

    今天传说中的微信4.0版本终于发布并且推送了更新,一进入是新...

  • vijos中c的注意事项

    昨天没事发现了一个叫vijos的类似judgeonline的网站,也许是我火星...

  • falcon编译出错问题

    ...

  • 教你破解xp系统administrator权限

    作者:Awolf 首发:AwolfS Security Blog 一.事情起因 那天满头大汗的...

  • Linux环境下UglifyJS安装

    Linux环境下UglifyJS安装 1.1.   安装 Node.js [[email protected] src]# wget http...