内核笔记:完成变量completion.
来源:互联网 发布:淘宝上买港版iphone6s 编辑:程序博客网 时间:2024/05/17 01:58
一结构体变量定义:
25 struct completion { 26 unsigned int done; //决定进程是否睡眠等待 27 wait_queue_head_t wait; //进程在此睡眠等待 28 };
二相关函数:
睡眠等待:
91 extern void wait_for_completion(struct completion *);92 extern void wait_for_completion_io(struct completion *);
93 extern int wait_for_completion_interruptible(struct completion *x);
94 extern int wait_for_completion_killable(struct completion *x);
95 extern unsigned long wait_for_completion_timeout(struct completion *x,
96 unsigned long timeout);
97 extern unsigned long wait_for_completion_io_timeout(struct completion *x,
98 unsigned long timeout);
99 extern long wait_for_completion_interruptible_timeout(
100 struct completion *x, unsigned long timeout);
101 extern long wait_for_completion_killable_timeout(
102 struct completion *x, unsigned long timeout);
以上函数实际都会调用wait_for_common()--->do_wait_for_common()
唤醒:
106 extern void complete(struct completion *); //completion->done +1,一次只满足一个进程
107 extern void complete_all(struct completion *);//completion->done增幅很大, 进程不会再进入睡眠.
* 以上函数实际都会调用__wake_up_common()
三流程图
不管是执行complete(x)还是wait_for_completion(x)都必须要抢占x->wait.lock.
因此可能出现这种情况:x->done为0.当进程A执行wait_for_completion(x)后等待x而进入睡眠。进程B执行了complete()后唤醒了进程A。但是在进程A抢占x->wait.lock前, 同样执行wait_for_completion(x)的进程C先抢占到了锁。获得x->done后离开,x->done再次变为0。而当A获得锁检查x->done已经为0, A 又再次进入睡眠.
四:类比
* 完成变量x好比是一个大仓库. x->done是仓库里的记货员。
*执行wait_for_completion()的进程为提货人。
* 执行complete()的进程为送货人。
*仓库有锁,一次只能进一个人,出仓库时钥匙挂门口。
* 提货人和送货人来的顺序不可知。 一件货只能一个人提。
1)当是提货A人先来到仓库, 他取下钥匙,进了仓库锁上大门。接着询问记货员有没有货, 如果有货,他立刻提货走人。如果没货,他就离开仓库还回钥匙,到仓库合营的酒店睡觉。
2)当送货人B来到仓库, 取消钥匙进了仓库,存好货物。记货员登记以后, 便打电话(或广播)通知在酒店里睡觉的提货人,如果有的话。送货人换回钥匙就离开了。
3)提货人听到电话(或广播)便立即赶到仓库提货, 提到货和记货员登记便执行离开。但是因为酒店和仓库有点远, 在提货人A赶到仓库时,很可能有提货人C已经提走了货.
扩展:
1) 提货人A可能摊上大事要赶火车, 所以他只能等timeout小时.如果这时间内没货, 他就携款潜逃了。wait_for_completion_timeout();
2) 提货人A还有其他任务, 如果但他接到老板的电话还没有领到货, 他也不管了.。 wait_for_completion_interruptible();
还有可能这个电话是用来引爆A身上的定时炸弹。。。。 wait_for_completion_killable()
3) 送货人B送的货太多,足够所有的提货人来提取。 complete_all()
五小技巧:
假设驱动模块使用了完成变量,在驱动移除时因为有进程在等待完成变量而进入睡眠导致无法移除。
可尝试
a).cat /proc/kallsyms | grep 'completion_name'若completion_name 0xfb002238写简单的模块:
b)
static int __init complete_init(void){ complete((struct completion*)0xfb002238);}c)加载模块以完成完成变量
- 内核笔记:完成变量completion.
- 完成量基础知识 ( completion )
- 完成例程(Completion Routine)
- 完成端口(Completion Port)
- 完成量completion实验
- linux completion 完成量
- 内核线程 && completion使用方法
- 内核的completion机制
- Linux内核同步:completion
- 9.7 内核同步方法_完成变量
- 完成端口(I/O completion):
- 完成端口(I/O completion):
- 完成端口(I/O completion)
- 完成端口(I/O completion)
- 完成端口(I/O completion):
- 完成端口(Completion Port)详解
- 完成端口(Completion Port)详解
- 完成端口(Completion Port)详解
- Java7中的switch支持String的实现细节
- linux命令之cash修改shell命令
- 特殊属性(__attribute__)
- UITextField
- Shareplex SP_SYS_HOST_NAME=localhost的一次错误
- 内核笔记:完成变量completion.
- 读者调查—读者研究购买行为及偏好
- Android问题之res/raw和assets文件大小限制
- Flex 视频监控多屏播放
- 读写锁和普通实现实现多线程读写者
- android驱动 无法打开设备文件 解决
- Scala School 笔记(四)--类型和多态基础
- python 学习笔记12-----网络编程
- nginx 301重定向方法