删除等待信号量的 kthread 的正确方法将被提升
Right way to delete kthread waiting while semaphore will be upped
我编写了一个使用内核线程和信号量的内核模块。
我从中断处理程序调用 up(...)
信号量函数,然后我的 kthread 开始执行。
static int interrupt_handler_thread(void *data)
{
/* duty cycle */
while (!kthread_should_stop()) {
/*
* If semaphore has been uped in the interrupt, we will
* acquire it here, else thread will go to sleep.
*/
if (!down_interruptible(mysem)) {
/* proccess gpio interrupt */
dev_info(dev, "gpio interrupt detected\n");
}
}
do_exit(0);
return 0;
}
信号量和线程初始化到module_init函数中。省略了错误检查。
...
sema_init(mysem, 0);
thread = kthread_create(interrupt_handler_thread,client,"my_int_handler");
wake_up_process(thread);
...
并且在卸载模块期间,信号量和线程被删除:
/*
* After this call kthread_should_stop() in the thread will return TRUE.
* See https://lwn.net/Articles/118935/
*/
kthread_stop(thread);
/*
* Release the semaphore to return
* from down_interruptible() function
*/
up(mysem);
当我尝试卸载我的模块时,它冻结在 down_interruptible()
函数的线程中,因为它在中断处理程序中等待信号量上升。我的代码从来没有 returns 来自 kthread_stop()
.
看来,我需要禁用我的 gpio 的中断,手动调高信号量并调用 kthread_stop()
函数。但这是一个潜在的错误,因为在手动增加信号量后,线程开始执行并且线程可以在其占空比后再次down_interruptible()
。
有人能帮帮我吗?
PS:我知道,但是,看来,这不是我的情况。
为了正确操作,您的 kthread 在等待信号量时应该检查 "stop" 线程的状态。不幸的是,没有 "stoppable" 版本的 down
函数。
而不是 kthread 使用 workqueue 机制。 Works 已经拥有您需要的所有功能:
- 您可以在中断处理程序 (
queue_work
) 中添加一个工作,
- 只能同时运行一个作品,
- 使用
destroy_workqueue
您可以安全地完成所有作品。
实际上,工作队列是使用 kthreads 实现的。参见例如kthread_worker_fn 函数的实现。
我编写了一个使用内核线程和信号量的内核模块。
我从中断处理程序调用 up(...)
信号量函数,然后我的 kthread 开始执行。
static int interrupt_handler_thread(void *data)
{
/* duty cycle */
while (!kthread_should_stop()) {
/*
* If semaphore has been uped in the interrupt, we will
* acquire it here, else thread will go to sleep.
*/
if (!down_interruptible(mysem)) {
/* proccess gpio interrupt */
dev_info(dev, "gpio interrupt detected\n");
}
}
do_exit(0);
return 0;
}
信号量和线程初始化到module_init函数中。省略了错误检查。
...
sema_init(mysem, 0);
thread = kthread_create(interrupt_handler_thread,client,"my_int_handler");
wake_up_process(thread);
...
并且在卸载模块期间,信号量和线程被删除:
/*
* After this call kthread_should_stop() in the thread will return TRUE.
* See https://lwn.net/Articles/118935/
*/
kthread_stop(thread);
/*
* Release the semaphore to return
* from down_interruptible() function
*/
up(mysem);
当我尝试卸载我的模块时,它冻结在 down_interruptible()
函数的线程中,因为它在中断处理程序中等待信号量上升。我的代码从来没有 returns 来自 kthread_stop()
.
看来,我需要禁用我的 gpio 的中断,手动调高信号量并调用 kthread_stop()
函数。但这是一个潜在的错误,因为在手动增加信号量后,线程开始执行并且线程可以在其占空比后再次down_interruptible()
。
有人能帮帮我吗?
PS:我知道
为了正确操作,您的 kthread 在等待信号量时应该检查 "stop" 线程的状态。不幸的是,没有 "stoppable" 版本的 down
函数。
而不是 kthread 使用 workqueue 机制。 Works 已经拥有您需要的所有功能:
- 您可以在中断处理程序 (
queue_work
) 中添加一个工作, - 只能同时运行一个作品,
- 使用
destroy_workqueue
您可以安全地完成所有作品。
实际上,工作队列是使用 kthreads 实现的。参见例如kthread_worker_fn 函数的实现。