内核中的许多部分初始化某些活动为单独的执行线程,然后等待这些线程完成。完成接口是一种有效并简单的方式来实现这样的代码模式。
对象创建:
DECLARE_COMPLETION(my_completion);
或
struct completion my_completion;/* … */
init_completion(&my_completion);
操作:
void wait_for_completion(struct completion *c); //执行一个不可中断的等待
void complete(struct completion *c);//唤醒一个线程
void complete_all(struct completion *c);//唤醒多个线程i
当调用complete时,可重用completion对象,当调用complete_all时,需要重新初始化后才能重用complete对象,可使用宏INIT_COMPLETION(struct completion c);
/***********************************************************************/
//完成接口
//内核中的许多部分初始化某些活动为单独的执行线程,然后等待这些线程完成。
//完成接口是一种有效并简单的方式来实现这样的代码模式。
/***********************************************************************/
#include<linux/completion.h>
#include<linux/module.h>
#include<linux/sched.h>
#include<linux/init.h>
staticDECLARE_COMPLETION(my_thread_exit);/* Completion */
staticDECLARE_WAIT_QUEUE_HEAD(my_thread_wait); /* Wait Queue */
intpink_slip = 0; /* Exit Flag */
/*Helper thread */
staticint
my_thread(void*unused)
{
DECLARE_WAITQUEUE(wait,current);
daemonize("my_thread");
add_wait_queue(&my_thread_wait,&wait);
while(1) {
/*Relinquish processor until event occurs */
set_current_state(TASK_INTERRUPTIBLE);
schedule();
/*Control gets here when the thread is woken
upfrom the my_thread_wait wait queue */
/*Quit if let go */
if(pink_slip) {
break;
}
/*Do the real work */
/*… */
}
/*Bail out of the wait queue */
__set_current_state(TASK_RUNNING);
remove_wait_queue(&my_thread_wait,&wait);
/*Atomically signal completion and exit */
complete_and_exit(&my_thread_exit,0);
}
/*Module Initialization */
staticint __init
my_init(void)
{
/*… */
/*Kick start the thread */
kernel_thread(my_thread,NULL,
CLONE_FS| CLONE_FILES | CLONE_SIGHAND | SIGCHLD);
/*… */
return0;
}
/*Module Release */
staticvoid __exit
my_release(void)
{
/*… */
pink_slip= 1; /* my_thread must go */
wake_up(&my_thread_wait); /* Activate my_thread */
wait_for_completion(&my_thread_exit);/* Wait until my_thread
quits */
/*… */
}
module_init(my_init);
module_exit(my_release);
今天不想走,明天就要跑了。