• Linux并发控制解决竞态的一种操作>原子操作


    -解决竞态的一种操作--->原子操作

      解决竞态的途径是“保证对共享资源的互斥访问

    原子操作

      原子的操作指的就是在执行过程中不会被别的代码所中断的操作。

      在Linux中原子操作的方法有很多,有整型原子和位原子,他们在任何情况下操作都是原子的,这些原子操作的实现都是依赖CPU来实现的,因此这些函数都与CPU架构密切相关。

    整型原子

      arm架构的原子实现在kernel/arch/arm/include/asm/atomic.h

      内核中提供的宏定义 :

      1. 设置源自变量的值

            

                static inline void atomic_set(atomic_t *v, int i); //设置原子的值   
                atomic_t = ATOMIC_INIT(0);          //定义原子变量并且初始化为0         

      2. 获取原子变量的值

      1. #define atomic_read(v)  ((v)->counter)   //返回原子变量的值  (*(volatile int *)&(v)->counter)

      3. 原子变量加减,自增自减

      1. #define atomic_add(i, v)    (void) atomic_add_return(i, v) //把v的值加 i
        #define atomic_inc(v)       (void) atomic_add_return(1, v)     //vz自加
        #define atomic_sub(i, v)    (void) atomic_sub_return(i, v)   
        #define atomic_dec(v)       (void) atomic_sub_return(1, v)   //v自减

      4. 操作并测试 

      open_atomic_int_one以及open_atomic_int_two两个程序
      要对/dev/atomic_int设备节点镜像操作
      先运行的程序1,将变量赋值为1,释放的时候赋值为0
      如果程序1在没有释放的情况下,程序2调用设备节点则会直接返回,无法调用。

    #include <linux/init.h>
    #include <linux/module.h>
    
    /*驱动注册的头文件,包含驱动的结构体和注册和卸载的函数*/
    #include <linux/platform_device.h>
    /*注册杂项设备头文件*/
    #include <linux/miscdevice.h>
    /*注册设备节点的文件结构体*/
    #include <linux/fs.h>
    //原子操作的函数头文件
    #include <asm/atomic.h>
    #include <asm/types.h>
    
    #define DRIVER_NAME "atomic_int"
    #define DEVICE_NAME "atomic_int"
    MODULE_LICENSE("Dual BSD/GPL");
    MODULE_AUTHOR("HKY");
    
    //定义原子变量,并初始化为0
    static atomic_t value_atomic = ATOMIC_INIT(0);
    
    static int atomic_int_open(struct inode *inode, struct file *file){
        printk(KERN_EMERG "atomic_int open in!\n");    
        
        if(atomic_read(&value_atomic)){
            return -EBUSY;
        }
        
        atomic_inc(&value_atomic);
        
        printk(KERN_EMERG "atomic_int open success!\n");    
        return 0;
    }
    
    static int atomic_int_release(struct inode *inode, struct file *file){
        printk(KERN_EMERG "atomic_int release\n");
        
        atomic_dec(&value_atomic);
        
        return 0;
    }
    
    static struct file_operations atomic_int_ops = {
        .owner = THIS_MODULE,
        .open = atomic_int_open,
        .release = atomic_int_release,
    };
    
    
    static  struct miscdevice atomic_int_dev = {
        .minor = MISC_DYNAMIC_MINOR,
        .name = DEVICE_NAME,
        .fops = &atomic_int_ops,
    };
    
    
    static int atomic_int_probe(struct platform_device *pdv){
        
        printk(KERN_EMERG "\tinitialized\n");
        misc_register(&atomic_int_dev);
        
        return 0;
    }
    
    static int atomic_int_remove(struct platform_device *pdv){
        
        printk(KERN_EMERG "\tremove\n");
        misc_deregister(&atomic_int_dev);
        return 0;
    }
    
    struct platform_driver atomic_int_driver = {
        .probe = atomic_int_probe,
        .remove = atomic_int_remove,
        .driver = {
            .name = DRIVER_NAME,
            .owner = THIS_MODULE,
        }
    };
    
    
    static int atomic_int_init(void)
    {
        int DriverState;
        
        printk(KERN_EMERG "HELLO WORLD enter!\n");
        DriverState = platform_driver_register(&atomic_int_driver);
        
        printk(KERN_EMERG "\tDriverState is %d\n",DriverState);
        return 0;
    }
    
    
    static void atomic_int_exit(void)
    {
        printk(KERN_EMERG "HELLO WORLD exit!\n");
        
        platform_driver_unregister(&atomic_int_driver);    
    }
    
    module_init(atomic_int_init);
    module_exit(atomic_int_exit);
  • 相关阅读:
    母爱——值得你用一生去回报
    cmd命令介绍
    对即将步入软件行业的师弟师妹们的忠告
    推荐4本c语言宝书
    不用判断语句如if,?:等来实现比较2个数
    javascript 浏览器不同的一个差异
    更新数据的经典代码
    允许 ASP.NET 服务器控件在 Page 中发出客户端脚本块的方法Page.RegisterClientScriptBlock 方法 [C#]
    使用多个表进行查询
    根据按钮的不同的CommandArgument处理每个按钮的单击事件的代码
  • 原文地址:https://www.cnblogs.com/hkyst/p/7605985.html
Copyright © 2020-2023  润新知