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);
时间: 2024-10-01 04:51:15

Linux并发控制---解决竞态的一种操作--->原子操作的相关文章

linux并行与竞态

内核态的竞态与并行 中断屏蔽: local_irq_save(flags) local_irq_restore(flags) Telnet 192.168.x.x登录开发板 #if 0 ...... #endif 原子操作 原子操作指的是在执行过程中不会被别的代码所中断的操作. 分为 位 和 整型变量 两类原子操作. void atomic_set(atomic_t *v, int i);   //设置原子变量v的值为i atomic_t v = ATOMIC_INIT(0);         

Linux内核分析(七)----并发与竞态

Linux内核分析(七) 这两天家里的事好多,我们今天继续接着上一次的内容学习,上次我们完善了字符设备控制方法,并深入分析了系统调用的实质,今天我们主要来了解一下并发和竞态. 今天我们会分析到以下内容: 1.      并发和竞态简介 2.      竞态解决办法 3.      为我们的虚拟设备增加并发控制 在前几次博文我们已经实现了简单的字符设备,看似完美但我们忽视了一个很严重的问题,即并发问题,那么什么是并发,又如何解决并发呢,我们下面进行分析. l  并发和竞态简介 1.       并

linux设备驱动系列:如何处理竞态关系

综述 在上一篇介绍了linux驱动的调试方法,这一篇介绍一下在驱动编程中会遇到的并发和竟态以及如何处理并发和竞争. 首先什么是并发与竟态呢?并发(concurrency)指的是多个执行单元同时.并行被执行.而并发的执行单元对共享资源(硬件资源和软件上的全局.静态变量)的访问则容易导致竞态(race conditions).可能导致并发和竟态的情况有: SMP(Symmetric Multi-Processing),对称多处理结构.SMP是一种紧耦合.共享存储的系统模型,它的特点是多个CPU使用共

LINUX设备驱动程序笔记(四)并发和竞态

       <一>.并发及其管理 大部分竞态可通过使用内核的并发控制原语,并应用几个基本的原理来避免.第一个规则是,只要可能,就应该避免资源的共享,这种思想的明显应用就是避免使用全局变量.但硬件资源本质上就是共享的,软件资源经常需要对其他执行线程可用.全局变量并不是共享数据的唯一途径,只要我们的代码将一个指针传递给了内核的其他部分,一个新的共享就可能建立.在单个执行线程之外共享硬件或软件资源的任何时候,因为另外一个线程可能产生对该资源的不一致观察,因此必须显示地管理对该资源的访问.访问管理的

linux设备驱动归纳总结(四):5.SMP下的竞态和并发

linux设备驱动归纳总结(四):5.多处理器下的竞态和并发 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx 这节将在上一节的基础上介绍支持多处理器和内核抢占的内核如何避免并发.除了内核抢占和中断外,由于多处理起的缘故,它可以做到多个程序同时执行.所以,进程除了要防自己的处理器外,还要防别的处理器,这个就是这节要介绍的内容. xxxxxxxxxxxxxxxxxxxxxxx

Hasen的linux设备驱动开发学习之旅--linux设备驱动中的并发与竞态

/** * Author:hasen * 参考 :<linux设备驱动开发详解> * 简介:android小菜鸟的linux * 设备驱动开发学习之旅 * 主题:linux设备驱动中的并发与竞态 * Date:2014-11-04 */ 1.并发与竞态 并发(concurrency)指的是多个执行单元同时.并行被执行,而并发的执行单元对共享资源(软件上的全 局变量,静态变量等)的访问则很容易导致竞态(race conditions). 主要的竞态发生在以下几种情况: (1)对称多处理(SMP)

《Linux Device Drivers》第五章 并发和竞态——note

并发及其管理 竞态通常作为对资源的共享访问结果而产生 当两个执行线程需要访问相同的数据结构(或硬件资源)时,并发的可能性就永远存在 只要可能就应该避免资源的共享,但共享通常是必须的,硬件本质上就是共享的 访问管理的常见技术称为"锁定"或者"互斥" 信号量和互斥体 建立临界区:在任意给定的时刻,代码只能被一个线程执行 可以使用一种锁定机制,当进程在等待对临界区的访问时,此机制可让进程进入休眠状态 一个信号量本质上是一个整数值,它和一对函数联合使用,这一对函数通常称为P

LDD3阅读笔记之内核中的并发和竞态

内核中的并发和竞态 一般驱动程序运行在内核态中,只能调用内核空间中提供的函数,因此在处理并发和竞态时不能使用用户空间提供的库,如pthread库,内核有着自己的一套内部实现机制. 并发及其管理 现代Linux系统中存在大量的并发来源,因此会导致可能的竞态.SMP系统甚至可能在不同的处理器上同时执行我们的代码.内核代码是可抢占的,因此,我们的驱动程序代码可能在任何时候丢失对处理器的独占,而拥有处理器的进程可能正在调用我们的驱动程序代码.设备中断是异步事件,也会导致代码的并发执行.内核还提供了很多可

并发与竞态

linux驱动--并发和竟态 序--正在运行的多个用户空间程序可能以一个令人惊讶的组合方式访问我们的代码.SMP系统甚至可能在不同的处理器上同时执行我们的代码.内核代码是可抢占的,因此我们的驱动程序代码可在任何时候丢失对处理器的独占. 信号量(semaphore)的实现: 有一对函数,通常成为P和V,加锁用P,解锁用V.在任何时刻只能有单个执行上下文拥有时,这种模式一个信号量也称谓"互斥体(mutex)".Linux内核中几乎所有信号量均用于互斥. 内核代码必须包括<asm/se