基本上我使用kthread_create()
创建了一个内核线程。 kthread反复做了一些事情。
while() {
//do something
msleep_interruptible(1000);
}
同时,我想在达到某个条件时终止此kthread(例如,调用特定的系统调用,或者终止特定的用户空间进程)。我已阅读kthread.c,但只找到了kthread_stop()
,这与kill -9
不同。它的作用只是设置KTHREAD_SHOULD_STOP
中的kthread->flag
位,并且在kthread函数体内必须调用kthread_should_stop()
来查询该位并自行调用do_exit()
我尝试过以下方法。问题是,当调用kthread_stop()
时,kthread通常处于睡眠状态(即msleep_interruptible(1000)
)。因此,我总是观察到调用kthread_stop()
和kthread确实退出之间的延迟。这导致了我的项目中无法忍受的延迟。我想要的就像kill -9
,也就是说,kthread会在我调用kthread_stop()
后立即终止。想法意识到了吗?
while(!kthread_should_stop()) {
//do something
msleep_interruptible(1000);
}
答案 0 :(得分:0)
我找到了解决问题的方法。这不是因为睡眠(即msleep_interruptible(1000)
)。实际上,此功能确实允许中断,kthread_stop()
也会执行wake_up_process()
以在设置KTHREAD_SHOULD_STOP
后唤醒目标k线程。所以理想情况下不应该有任何问题,这意味着无论msleep_interruptible()
的参数如何,每当调用kthread_stop()
时,kthread应该被唤醒并很快终止。
然而,有一个"失去了醒来"竞争条件(我受到this post的启发,这显示了与我类似的问题)。棘手的是msleep_interruptible()
基本上包含两个方法set_current_state(TASK_INTERRUPTIBLE);
和schedule_timeout();
,并且kthread_stop()
可以在两个方法之前执行。所以订单会这样:
[kthread]: //do something
[my syscall]: wake_up_process(kthread); //inside kthread_stop()
[kthread]: set_current_state(TASK_INTERRUPTIBLE);
[kthread]: schedule_timeout();
因此,kthread将简单地忽略wake_up_process()
。要解决此问题,必须将set_current_state(TASK_INTERRUPTIBLE);
和schedule_timeout();
分离。以下代码到目前为止工作正常。
while(!kthread_should_stop()) {
//do something
set_current_state(TASK_INTERRUPTIBLE);
if (kthread_should_stop()) {
break;
}
schedule_timeout();
}
从这个意义上讲,确实在内核中退出了一种杀死kthread的方法,就像kill -9
一样。