欢迎来到天天文库
浏览记录
ID:28033760
大小:459.41 KB
页数:12页
时间:2018-12-07
《驱动中的并发控制方法》由会员上传分享,免费在线阅读,更多相关内容在学术论文-天天文库。
1、4月10日驱动中的并发控制方法一、并发控制原理简介1、驱动屮产生并发控制需求的原因一个硬件会并发的被多个进程使用,因此驱动中的读写函数会被不同的进程并发执行。例如scull设备就有可能在A进程正在执行scull_rcad函数(但尚未执行完)的时候,就被B进程打断,而B进程执行的是scull_write函数,当A进程再次被执行的时候它读到的东西就不再是它以前应该读到的东西。这还不是最严重的,如果是2个进程并发执行scull」r4te,就有可能导致内存泄露以及丢失某个进程写入的数据。为什么会这样?请在分析scull_write
2、函数的时候,假想A进程在执行该函数时有可能随时被B进程打断。要解决这个问题,就必须保证当scull_read或scull_write在执行时不被打断,这就需要并发控制。2、并发控制的原理•在任何给定吋间只有一个线程可以执行的代码段被称为临界区(例如scull_writc屮不能被打断的代码)。•使用信号量和P、V操作保护临界区。一个信号量的核心是一个单个整型值,结合有一对函数P和Vo一个想进入临界区的进程将在相关信号量上调用P;如果信号量的值大于零,这个值递减1并U进程继续。相反,如果信号量的值是0(或更小),进程必须等待直
3、到别人释放信号量。解锁一个信号量通过调用V完成;这个函数递増信号量的值,如果需要,唤醒等待的进程。Linux操作系统提供给驱动程序进行并发控制的手段主要有5种,最常用的是信号量和自旋锁:•信号量•自旋锁•读/写信号量•读写自旋锁•Completions机制二、信号量的实现1、信号量操作方法1)、定义及初始化•普通信号量定义以及初始化:ostructsemaphoreovoidsema_init(structsemaphore*sem,intval);•互斥锁(2值信号量)的声明与初始化:ODECLAREJ1UTEX(nam
4、e);oDECLARE_MUTEX_LOCKED(name);•如果互斥锁必炭在运行时间初始化使用下列宏:ovoidinit_MUTEX(structsemaphore*sem);ovoidinit_MUTEX_LOCKED(struetsemaphore*sem);2)、信号量操作函数•voiddown(structsemaphore*sem),递减信号量值,如果需要则深度睡眠。它其实就是前面讲的P操作。•intclown_interruptible(struetsemaphore*sem),含义同上,但是是浅度睡眠•d
5、owntrylock从不睡眠,如果信号量在调用时不可用,downtrylock立刻返冋一个非零值•voidup(structsemaphore*scm);—旦up被调用,调用者就不再拥有信号量,如有需要则唤醒睡眠在该信号量上的进程。它其实就是前面讲的V操作特别说明:•ps中用D+表示深度唾眠,用S+表示浅度唾眠;•深度睡眠不能被信号屮断(即使SIGKILL也不行);浅度睡眠能被信号屮断•downinterruptible返回值为int,可以通过返回值判定进程被唤醒的原因是占于其它进程执行了up,还是由于收到了信号;down
6、返回值为void,因为down不能被信号中断2、scull设备驱动中是如何使用信号量进行并发控制的?1)、定义(位于scull,h中)88structsculldev{/*Pointertofirst89struetscull_qset*data;quantiimset*/95semaphore100structure101};structsemaphoresem;*/structcdevcdev;*//*mutueilexclusion/*Chardevice2)、初始化(位于main,c的驱动初始化函数中)713717
7、for(i=0;i8、后,insmodscull,ko去掉333、345行的注释333345sslccp(5);ssleep(5);2)、写入数据:echoyang>./scul103)、并发读出数据cat•/soul10&cat•/scullO4)、查看驱动的输出:tail/var/log/syslog1pr916:26:
8、后,insmodscull,ko去掉333、345行的注释333345sslccp(5);ssleep(5);2)、写入数据:echoyang>./scul103)、并发读出数据cat•/soul10&cat•/scullO4)、查看驱动的输出:tail/var/log/syslog1pr916:26:
此文档下载收益归作者所有