字符驱动程序之——同步互斥阻塞

1. 原子操作

原子操作指的是在执行过程中不会被别的代码路径所中断的操作。
常用原子操作函数举例:
atomic_t v = ATOMIC_INIT(0); //定义原子变量v并初始化为0
atomic_read(atomic_t *v); //返回原子变量的值
void atomic_inc(atomic_t *v); //原子变量增加1
void atomic_dec(atomic_t *v); //原子变量减少1
int atomic_dec_and_test(atomic_t *v); //自减操作后测试其是否为0,为0则返回true,否则返回false。

2. 信号量
信号量(semaphore)是用于保护临界区的一种常用方法,只有得到信号量的进程才能执行临界区代码。
当获取不到信号量时,进程进入休眠等待状态。

定义信号量
struct semaphore sem;
初始化信号量
void sema_init (struct semaphore *sem, int val);
void init_MUTEX(struct semaphore *sem);//初始化为0

static DECLARE_MUTEX(button_lock); //定义互斥锁

获得信号量
void down(struct semaphore * sem);
int down_interruptible(struct semaphore * sem);
int down_trylock(struct semaphore * sem);
释放信号量
void up(struct semaphore * sem);

3. 阻塞
阻塞操作
是指在执行设备操作时若不能获得资源则挂起进程,直到满足可操作的条件后再进行操作。
被挂起的进程进入休眠状态,被从调度器的运行队列移走,直到等待的条件被满足。

非阻塞操作
进程在不能进行设备操作时并不挂起,它或者放弃,或者不停地查询,直至可以进行操作为止。

fd = open("...", O_RDWR | O_NONBLOCK);

利用原子访问实现驱动层函数只被一个任务调用(有同步线程的功能):

首先定义一个原子变量初始值为1:

在open函数中增加判断,这个是原子操作:

如果是第一次调用,if就不会满足,第一次的时候自减操作为0,自减函数为0返回true,取反就是false,不执行。

当open函数同时被其他进程再次调用时,由于第一次调用的进程没有释放资源,自减操作为-1,if条件满足,先恢复之前原子变量的状态,然后返回错误代码我忙碌的状态,此时应用程序可以得到不能打开该文件的提示。

APP测试程序如下:

终端现象入下:

多次后台运行应用程序会出现不能打开的提示,第一次则不会。同时按键依旧有效。

利用互斥机制实现同一个应用程序同时只被一个进程调用:

先定义一个互斥信号量:

在open函数中获取信号量:第一次来获取的时候,没有任何问题,在没有释放的情况下又一个线程来获取信号量的时候就需要等待第一次获取的线程释放了之后才可以。

在close函数中释放信号量:

应用程序后台运行并查看PID,此时为809:

再次后台运行应用程序,并查看PID,此时为811:

注意,这里的809,也就是第一次后台运行的时候,是处于S状态(可中断的睡眠状态),而在第一次没有释放信号量的时候,第二次后台运行应用程序显示的是D状态(不可中断状态,不是cpu不响应外部中断,而是该进程不响应异步信号)。

什么是不可中断状态呢?比如这里我们要kill掉这个进程,但由于811处于D状态,是不响应kill信号的。

现在我们把第一个进程809给kill掉(释放了信号量),此时会发现811变成了S状态,可以被异步信号触发了。

实验的时候意外发现,虽然刚才我们kill 811被拒绝了,但是当我kill 809之后,811被自动kill了,说明linux这里有保存操作的功能。

在互斥信号的时候不释放就再次打开不会提示can‘t open.而是进入休眠状态。

阻塞与非阻塞:

在open中判断应用程序是不是非阻塞的读取:

down_trylock如果无法获取信号量,立即返回。

应用程序,使用非阻塞的情况,阻塞情况前面的学习中已经实验过了:

终端显示:

没有按键下的时候,ret一直为-1

有按键的时候:

有按键时候,就不会返回-1.

but,是不是和我在看韦老师实验的时候一样,如同上图一样,明明有些地方有按键值,但是ret却是-1啊!!!

难道是驱动写出bug了?可韦老师的也是这样的现象啊。

Answer:

bug是有,但不是这里的非阻塞驱动,是我的按键程序,在按键按下之后是一个值,松开之后是另外一个,在没有按键的时候,应该将这个按键值清零才对。

更改read驱动函数如下:

这样更改了之后,没有按键的时候就是0键值,ret为-1,有按键的时候就是返回键值,ret为1.

进步是有的,能够发现老师代码bug了。每天给自己一点鼓励,前路漫漫其修远,吾将上下而求索。

韦老师也说了更加深入的知识点需要看更多的书籍,这里只是简单的入门介绍。

原文地址:https://www.cnblogs.com/yangguang-it/p/8976496.html

时间: 2024-08-26 05:05:17

字符驱动程序之——同步互斥阻塞的相关文章

字符设备驱动程序之同步互斥阻塞

目的:在同一时刻,只有一个应用程序打开/dev/buttons 驱动程序: #include <linux/module.h>#include <linux/kernel.h>#include <linux/fs.h>#include <linux/init.h>#include <linux/delay.h>#include <linux/irq.h>#include <asm/uaccess.h>#include &l

字符设备驱动------同步互斥阻塞

引入 当设备被一个程序打开时,存在被另一个程序打开的可能,如果两个或多个程序同时对设备文件进行写操作,这就是说我们的设备资源同时被多个进程使用,对共享资源(硬件资源.和软件上的全局变量.静态变量等)的访问则很容易导致竞态. 显然这不是我们想要的,所以本节引入互斥的概念:实现同一时刻,只能一个应用程序使用驱动程序 互斥其实现很简单,就是采用一些标志,当文件被一个进程打开后,就会设置该标志,使其他进程无法打开设备文件 目的 同一时刻,只允许驱动程序被一个进程打开 1.其中的标志需要使用函数来操作,不

入门级的按键驱动——按键驱动笔记之poll机制-异步通知-同步互斥阻塞-定时器防抖

文章对应视频的第12课,第5.6.7.8节. 在这之前还有查询方式的驱动编写,中断方式的驱动编写,这篇文章中暂时没有这些类容.但这篇文章是以这些为基础写的,前面的内容有空补上. 按键驱动——按下按键,打印键值: 目录 概要 poll机制 异步通知 同步互斥阻塞 定时器防抖 概要: 查询方式: 12-3 缺点:占用CPU99%的资源.中断方式:12-4 缺点:调用read函数后如果没有按键按下,该函数永远不会结束,一直在等待按键按下. 优点:使用到了休眠机制,占用cpu资源极少.poll机制: 1

Linux之同步互斥阻塞20160703

主要介绍一下Linux下的互斥与阻塞方面的知识: 1. 原子操作 原子操作指的是在执行过程中不会被别的代码路径所中断的操作. 常用原子操作函数举例: atomic_t v = ATOMIC_INIT(0);     //定义原子变量v并初始化为0 atomic_read(atomic_t *v);        //返回原子变量的值 void atomic_inc(atomic_t *v);    //原子变量增加1 void atomic_dec(atomic_t *v);    //原子变量

# 进程/线程/协程 # IO:同步/异步/阻塞/非阻塞 # greenlet gevent # 事件驱动与异步IO # Select\Poll\Epoll异步IO 以及selectors模块 # Python队列/RabbitMQ队列

1 # 进程/线程/协程 2 # IO:同步/异步/阻塞/非阻塞 3 # greenlet gevent 4 # 事件驱动与异步IO 5 # Select\Poll\Epoll异步IO 以及selectors模块 6 # Python队列/RabbitMQ队列 7 8 ############################################################################################## 9 1.什么是进程?进程和程序之间有什么

Linux中四种进程或线程同步互斥控制方法

原文地址:http://blog.itpub.net/10697500/viewspace-612045/ 一.Linux中 四种进程或线程同步互斥的控制方法: 1.临界区:通过对多线程的串行化来访问公共资源或一段代码,速度快,适合控制数据访问. 2.互斥量:为协调共同对一个共享资源的单独访问而设计的. 3.信号量:为控制一个具有有限数量用户资源而设计. 4.事 件:用来通知线程有一些事件已发生,从而启动后继任务的开始. 二.临界区(Critical Section) 保证在某一时刻只有一个线程

C++中四种进程或线程同步互斥的控制方法

现在流行的进程线程同步互斥的控制机制,其实是由最原始最基本的4种方法实现的.由这4种方法组合优化就有了.Net和Java下灵活多变的,编程简便的线程进程控制手段. 这4种方法具体定义如下 在<操作系统教程>ISBN 7-5053-6193-7 一书中能够找到更加周详的解释 1临界区:通过对多线程的串行化来访问公共资源或一段代码,速度快,适合控制数据访问. 2互斥量:为协调一起对一个共享资源的单独访问而设计的. 3信号量:为控制一个具备有限数量用户资源而设计. 4事 件:用来通知线程有一些事件已

【软考】PV操作同步互斥

进程 在操作系统中,进程是占有资源的最小单位(线程可以访问其所在进程内的所有资源,但线程本身并不占有资源或仅仅占有一点必须资源),一个进程能有多个线程. 临界资源 指一次只能有一个进程在占用的资源.如现实中的衣服.一件衣服只能一个人在穿.比如一个硬盘.有两个进程对同一块区域进行写操作.数据不就一锅粥了么= = 临界区 在一个进程占有临界资源的时候.别的进程不能占有.这是互斥.从进程占有资源到资源被释放.这一段代码就叫临界区. 临界区原则(有空即进-无空则等-有限等待-让权等待) 个人造词= =

驱动程序的同步处理

驱动程序的同步处理 Windows是个多任务的操作系统,每个任务对应一个运行的进程.每个运行的进程中可以包含多个线程.如果没有同步机制的控制,所有的线程会任意运行.然而,多个线程可能会要求操作同一个资源,这时就需要同步处理. 1.基本概念 1.1.问题的引出 在支持多线程的操作系统下,有些函数会出现不可重入现象.所谓"可重入",是指函数的执行结果和执行顺序无关.反之,如果执行结果和执行顺序有关,则称这个函数是"不可重入"的. "不可重入"的函数会