Completion,是一种轻量级的机制,它允许一个线程告诉另一个线程工作已经完成,用于多线程间同步,即线程A要往下执行需要等待线程B执行到指定代码后才继续执行,这时就可以使用该机制,用于一个线程告诉另一个线程指定工作已完成。 在Linux Kernel源码include/linux/completion.h文件里有相关的结构体和接口函数的定义和声明,从结构体可以看到其是基于等待队列机制实现的,
1 struct completion { 2 unsigned int done; 3 wait_queue_head_t wait; 4 }; 5 static inline void init_completion(struct completion *x) ; 6 static inline void reinit_completion(struct completion *x); 7 extern void wait_for_completion(struct completion *); 8 extern int wait_for_completion_interruptible(struct completion *x); 9 extern int wait_for_completion_killable(struct completion *x); 10 extern unsigned long wait_for_completion_timeout(struct completion *x, 11 unsigned long timeout); 12 extern long wait_for_completion_interruptible_timeout( 13 struct completion *x, unsigned long timeout); 14 extern long wait_for_completion_killable_timeout( 15 struct completion *x, unsigned long timeout); 16 extern bool try_wait_for_completion(struct completion *x); 17 extern bool completion_done(struct completion *x); 18 extern void complete(struct completion *); 19 extern void complete_all(struct completion *);
要等待completion,可进行如下调用:
void wait_for_completion(struct completion *c);
触发completion事件,调用:
void complete(struct completion *c); //唤醒一个等待线程
void complete_all(struct completion *c);//唤醒所有的等待线程
其中结构体中的done相当于一个统计量,当其为0时表示等待队列上还有线程在等待,如果大于0则表示有多少个线程等待的条件已完成,不需等待可继续执行。
init_completion初始化一个completion结构体,将done设置为0,并初始化wait等待队列头部。而 reinit_completion则是在complete_all执行后completion仍想继续使用时必须执行的函数。
wait_for_completion则等待创建的completion量完成,即等待complete或complete_done函数执行。而_interruptible则表示该等待可被信号中断,_killable则表示该等待可被kill信号打断,_timeout则表示该等待只等待有限的时间,还有其他的组合则是这3种条件的组成,而try_wait_for_completion则相当于wait_for_completion_timeout中timeout为0的情况。
completion_done则是个判断条件,返回0表示还有等待者,为1则没有等待者。