内核编程中常见的一种模式是,在当前线程之外初始化某个活动,然后等待该活动的结束。
这个活动可能是:创建一个新的内核线程或者新的用户空间进程、对一个已有进程的某个请求,或者某种类型的硬件动作。
可以使用信号量进行同步,但如果存在针对该信号量的严重竞争,性能将受到影响。
completion是一种轻量级的机制,它允许一个线程告诉另一个线程某个工作已经完成。
struct completion my_completion;
init_completion(&my_completion);
void wait_for_completion(struct completion *c);
该函数执行一个非中断的等待,如果代码调用了wait_for_completion且没有人会完成该任务,则将产生一个不可杀的进程。
complete只会唤醒一个等待线程。
void complete_all(struct completion *c);
complete_all允许唤醒所有等待线程。
下面这个宏可用来快速执行重新初始化:
INIT_COMPLETION(struct completion c);
completion机制的典型使用是模块退出时的内核线程终止。
在这种原型中,某些驱动程序的内部工作由一个内核线程在while(1)循环中完成。
当内核准备清除该模块时,exit函数会告诉该线程退出并等待completion。
为了实现这个目的,内核包含了可用于这种线程的一个特殊函数:
这个活动可能是:创建一个新的内核线程或者新的用户空间进程、对一个已有进程的某个请求,或者某种类型的硬件动作。
可以使用信号量进行同步,但如果存在针对该信号量的严重竞争,性能将受到影响。
如果使用信号量在任务完成时进行通信,则调用down的线程几乎总是要等待,这样性能也同样会受到影响。
completion是一种轻量级的机制,它允许一个线程告诉另一个线程某个工作已经完成。
为了使用completion,代码必须包含<linux/completion.h>。
接口:
DECLARE_COMPLETION(my_completion);struct completion my_completion;
init_completion(&my_completion);
void wait_for_completion(struct completion *c);
该函数执行一个非中断的等待,如果代码调用了wait_for_completion且没有人会完成该任务,则将产生一个不可杀的进程。
实际的completion事件可通过调用下面函数之一来触发:
void complete(struct completion *c);complete只会唤醒一个等待线程。
void complete_all(struct completion *c);
complete_all允许唤醒所有等待线程。
下面这个宏可用来快速执行重新初始化:
INIT_COMPLETION(struct completion c);
completion机制的典型使用是模块退出时的内核线程终止。
在这种原型中,某些驱动程序的内部工作由一个内核线程在while(1)循环中完成。
当内核准备清除该模块时,exit函数会告诉该线程退出并等待completion。
为了实现这个目的,内核包含了可用于这种线程的一个特殊函数:
void complete_and_exit(struct completion *c, long retval);
(摘自Linux设备驱动程序;
补充阅读:http://blog.csdn.net/dreamxu/article/details/5866593)