完成量:表示一个执行单元需要等待另一个执行单元完成某事后方可执行。
1.它是一种轻量级机制,为了完成进程间的同步而设计
2.使用完成量等待时,调用进程是以独占睡眠方式进行等待的
3.不是忙等待
理解:
定义于#include<linux/complete.h>
其结构体为
struct completion {
unsigned int done;
wait_queue_head_t wait;
};
其中,done变量是完成量要保护的对象,wait则是申请完成量的进程等待队列。
初始化函数
static inline void init_completion(struct completion *x)
{
x->done = 0;
init_waitqueue_head(&x->wait);
}
done变量被初始化为0.
内核代码中wait_for_common函数其实就是对done变量作判断,若done变量没有大于0,则它一直处于while循环中。
complete函数就是对done变量加1。wait_for_common函数便会退出while循环,同时将done减1,表示申请完成量成功。
操作:
struct completion my_completion; //定义完成量my_completion
init_completion(&my_completion); //初始化完成量my_completion
void wait_for_completion(struct completion* comp)
该函数等待一个完成量被唤醒。该函数会阻塞调用进程,如果所等待的完成量没有被唤醒,那就一直阻塞下去,而且不会被信号打断;
int wait_for_completion_interruptible(struct completion* comp)
该函数等待一个完成量被唤醒。但是它可以被外部信号打断;
int wait_for_completion_killable(struct completion* comp)
该函数等待一个完成量被唤醒。但是它可以被kill信号打断;
unsigned long wait_for_completion_timeout(struct completion* comp, unsigned long timeout)
该函数等待一个完成量被唤醒。该函数会阻塞调用进程,如果所等待的完成量没有被唤醒,调用进程也不会一直阻塞下去,而是等待一个指定的超时时间timeout,当超时时间到达时,如果所等待的完成量仍然没有被唤醒,那就返回;超时时间timeout以系统的时钟滴答次数jiffies计算
bool try_wait_for_completion(struct completion* comp)
该函数尝试等待一个完成量被唤醒。不管所等待的完成量是否被唤醒,该函数都会立即返回
bool completion_done(struct completion* comp)
该函数用于检查是否有执行单元阻塞在完成量comp上(是否已经完成),返回0,表示有执行单元被完成量comp阻塞;相当于wait_for_completion_timeout()中的timeout=0
void complete(struct completion* comp)
该函数只唤醒一个正在等待完成量comp的执行单元
void complete_all(struct completion* comp)
该函数唤醒所有正在等待同一个完成量comp的执行单元
NORET_TYPE void complete_and_exit(struct completion* comp, long code)
该函数唤醒一个正在等待完成量comp的执行单元,并退出,code为退出码
注意:在内核处理完请求之后,必须调用这三个函数中的一个,来唤醒其它正在等待的进程