内核线程同步之completion

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则没有等待者。




posted @ 2020-08-05 10:23  蒲城小农  阅读(1623)  评论(0)    收藏  举报