问一个completion的问题
completion 可以使用一个线程唤醒另外一个线程。
那么它跟 wake_up_interruptible 有什么区别么?? 这个函数同样也能唤醒另外一个线程啊
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
completion 可以使用一个线程唤醒另外一个线程。
那么它跟 wake_up_interruptible 有什么区别么?? 这个函数同样也能唤醒另外一个线程啊
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
接受
或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
发布评论
评论(3)
completion是一种轻量级的机制,它允许一个线程告诉另一个线程工作已经完成。可以利用下面的宏静态创建completion:
DECLARE_COMPLETION(my_completion);
如果运行时创建completion,则必须采用以下方法动态创建和初始化:
复制代码
要等待completion,可进行如下调用:
void wait_for_completion(struct completion *c);
触发completion事件,调用:
void complete(struct completion *c); //唤醒一个等待线程
void complete_all(struct completion *c); //唤醒所有的等待线程
为说明completion的使用方法,将<<Linux设备驱动程序>>一书中的complete模块的代码摘抄如下:
复制代码
该模块定义了一个简单的completion设备:任何试图从该设备中读取的进程都将等待,直到其他设备写入该设备为止。编译此模块的Makefile如下:
obj-m := complete.o
KDIR := /lib/modules/$(shell uname -r)/build
PWD := $(shell pwd)
default:
$(MAKE) -C $(KDIR) M=$(PWD) modules
clean:
rm -f *.ko *.o *.mod.c
在linux终端中执行以下命令,编译生成模块,并进行动态加载
# make
# mknod completion c 253 0
# insmod complete.ko
再打开三个终端,一个用于读进程:
# cat completion
一个用于写进程:
# echo >completion
另一个查看系统日志:
# tail -f /var/log/messages
值得注意的是,当我们使用的complete_all接口时,如果要重复使用一个completion结构,则必须执行INIT_COMPLETION (struct completion c)来重新初始化它。可以在kernel/include/linux/completion.h中找到这个宏的定义:
#define INIT_COMPLETION(x) ((x).done = 0)
以下代码对书中原有的代码进行了一番变动,将唤醒接口由原来的complete换成了complete_all,并且为了重复利用completion结构,所有读进程都结束后就重新初始化completion结构,具体代码如下:
复制代码
这里测试步骤和上述一样,只不过需要多打开几个终端来执行多个进程同时读操作。
我知道啊, 但是这些功能同样能够用 waike_up_interrutpible 完成啊
{
might_sleep();
spin_lock_irq(&x->wait.lock);
if (!x->done) {
DECLARE_WAITQUEUE(wait, current);
wait.flags |= WQ_FLAG_EXCLUSIVE;
__add_wait_queue_tail(&x->wait, &wait);
do {
__set_current_state(TASK_UNINTERRUPTIBLE);
spin_unlock_irq(&x->wait.lock);
schedule();
spin_lock_irq(&x->wait.lock);
} while (!x->done);
__remove_wait_queue(&x->wait, &wait);
}
x->done--;
spin_unlock_irq(&x->wait.lock);
}