- 1、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。。
- 2、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 3、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
- 4、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
- 5、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们。
- 6、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
- 7、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
查看更多
驱动中的并发控制方法
4月10日
驱动中的并发控制方法
一、并发控制原理简介
1、驱动中产生并发控制需求的原因
一个硬件会并发的被多个进程使用,因此驱动中的读写函数会被不同的进程并发执行。例如scull设备就有可能在A进程正在执行scull_read函数(但尚未执行完)的时候,就被B进程打断,而B进程执行的是scull_write函数,当A进程再次被执行的时候它读到的东西就不再是它以前应该读到的东西。这还不是最严重的,如果是2个进程并发执行scull_write,就有可能导致内存泄露以及丢失某个进程写入的数据。为什么会这样?请在分析scull_write函数的时候,假想A进程在执行该函数时有可能随时被B进程打断。要解决这个问题,就必须保证当scull_read或scull_write在执行时不被打断,这就需要并发控制。
2、并发控制的原理
在任何给定时间只有一个线程可以执行的代码段被称为临界区(例如scull_write中不能被打断的代码)。
使用信号量和P、V操作保护临界区。
一个信号量的核心是一个单个整型值, 结合有一对函数 P 和 V。一个想进入临界区的进程将在相关信号量上调用 P; 如果信号量的值大于零, 这个值递减 1并且进程继续。 相反, 如果信号量的值是 0( 或更小 ), 进程必须等待直到别人释放信号量。 解锁一个信号量通过调用 V 完成; 这个函数递增信号量的值, 如果需要, 唤醒等待的进程。
Linux操作系统提供给驱动程序进行并发控制的手段主要有5种,最常用的是信号量和自旋锁:
信号量
自旋锁
读/写信号量
读写自旋锁
Completions 机制
二、信号量的实现
1、信号量操作方法
1)、定义及初始化
普通信号量定义以及初始化:
struct semaphore
void sema_init(struct semaphore *sem, int val);
互斥锁(2值信号量)的声明与初始化:
DECLARE_MUTEX(name);
DECLARE_MUTEX_LOCKED(name);
如果互斥锁必须在运行时间初始化使用下列宏:
void init_MUTEX(struct semaphore *sem);
void init_MUTEX_LOCKED(struct semaphore *sem);
2)、信号量操作函数
void down (struct semaphore *sem),递减信号量值,如果需要则深度睡眠。它其实就是前面讲的P操作。
int down_interruptible (struct semaphore *sem),含义同上,但是是浅度睡眠?
down_trylock 从不睡眠,如果信号量在调用时不可用, down_trylock 立刻返回一个非零值
void up(struct semaphore *sem); 一旦 up 被调用,调用者就不再拥有信号量,如有需要则唤醒睡眠在该信号量上的进程。它其实就是前面讲的V操作
特别说明:
ps中用D+表示深度睡眠,用S+表示浅度睡眠;
深度睡眠不能被信号中断(即使SIGKILL也不行);浅度睡眠能被信号中断
down_interruptible返回值为int,可以通过返回值判定进程被唤醒的原因是由于其它进程执行了up,还是由于收到了信号;down返回值为void,因为down不能被信号中断
2、scull设备驱动中是如何使用信号量进行并发控制的?
1)、定义(位于scull.h中)
88 struct scull_dev {89???????? struct scull_qset *data;? /* Pointer to first quantum set */95??????? struct semaphore sem;???? /* mutual exclusion semaphore???? */100???????? struct cdev cdev;???????? /* Char device structure????????????? */101 };
2)、初始化(位于main.c的驱动初始化函数中)
713???????? for (i = 0; i scull_nr_devs; i++) {717???????????????? init_MUTEX(scull_devices[i].sem);721???????????????? scull_setup_cdev(scull_devices[i], i);722???????? }
3)、获得信号量(位于main.c的scull_write和scull_read函数中)
397???????? if (d
您可能关注的文档
最近下载
- U8V11.1培训课件9U8V11.1新版功能介绍生产制造幻灯片.ppt VIP
- GB_T 9711-2023 石油天然气工业 管线输送系统用钢管.pdf VIP
- 1kv母线调试报告.pdf VIP
- 过滤实验-课件.ppt VIP
- GB_T 14264-2024 半导体材料术语.pdf VIP
- 消防系统的联动常见故障.ppt VIP
- (完整版)供应商合规管理制度 .pdf VIP
- JBT 12786-2016 升降工作平台 术语与分类.pdf VIP
- 2024东南亚电商市场报告.pptx VIP
- 第七单元 跨学科主题学习——项目开展,探究丝绸之路 学习任务单 苏科版初中信息科技七年级下册.docx VIP
文档评论(0)