内核中的许多部分初始化某些活动为单独的执行线程,然后等待这些线程完成。完成接口是一种有效并简单的方式来实现这样的代码模式。
对象创建:
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); 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 quits */ /*... */ } module_init(my_init); module_exit(my_release); |