本文主要是介绍关于kthread_stop的疑问(linux3.16),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
线程一旦启动起来后,会一直运行,除非该线程主动调用do_exit函数,或者其他的进程调用kthread_stop函数,结束线程的运行。
之前找销毁内核线程的接口时,发现了kthread_stop这个接口。网上说这个函数能够销毁一个内核线程。
最开始以为对于一个已经唤醒的内核线程,我们直接调用这个接口就能够让这个线程自动退出。后面经过试验发现并不是这样的======》kthread_stop只是通知线程退出,至于线程是否会退出,取决于线程的行为,即是否有kthread_should_stop动作,去检查,去主动退出
测试代码1
static struct task_struct *test_task;
struct task_struct *task;
struct timer_list timer;
int test_thread(void* a)
{printk(KERN_EMERG "\r\n thread start\n");
#ifdef CONFIG_PREEMPT_COUNTprintk(KERN_EMERG "\r\n CONFIG_PREEMPT_COUNT\n");
#elseprintk(KERN_EMERG "\r\n not define CONFIG_PREEMPT_COUNT\n");
#endif while (1){if( kthread_should_stop()){printk(KERN_EMERG "\r\n exit while\n");break;}msleep(10000); }printk(KERN_EMERG "\r\n thread end\n");return 0;
}
int kill_thread(void* a)
{if (NULL != test_task){printk(KERN_EMERG "\r\n attempt kill test_thread\n");kthread_stop(test_task);printk(KERN_EMERG "\r\n kill test_thread complete\n");}return;
}
void timer_work(unsigned long data)
{wake_up_process(task);return;
}static int smsc911x_init(struct net_device *dev)
{
................ timer.expires=jiffies+msecs_to_jiffies(20000);timer.function=timer_work;init_timer(&timer);add_timer(&timer);printk(KERN_EMERG "\r\n create thread\n");//spin_lock(&lockdep_test);test_task = kthread_create(test_thread, NULL, "test_task");wake_up_process(test_task); task = kthread_create(kill_thread, NULL, "kill_task");//kthread_stop(test_task);printk(KERN_EMERG "\r\n create thread end\n");
.....................
}
log如下:可以看到在上面的代码样例中(kthread_should_stop必须要有这个),确实能够让内核线程退出
测试代码2
将内核线程的处理函数里面的kthread_should_stop去掉,其他保持不变。看看会发生什么
int test_thread(void* a)
{printk(KERN_EMERG "\r\n thread start\n");
#ifdef CONFIG_PREEMPT_COUNTprintk(KERN_EMERG "\r\n CONFIG_PREEMPT_COUNT\n");
#elseprintk(KERN_EMERG "\r\n not define CONFIG_PREEMPT_COUNT\n");
#endif while (1){/*if( kthread_should_stop()){printk(KERN_EMERG "\r\n exit while\n");break;}*/msleep(10000); }printk(KERN_EMERG "\r\n thread end\n");return 0;
}
log如下:可以看到。如果处理函数里面没有kthread_should_stop,即使通过kthread_stop通知内核线程应该退出了,但是内核线程不去检查是否应该退出,那么内核线程也是无法退出的。即kthread_stop是无法强制杀死内核线程的
测试 代码3
内核线程处理函数不要kthread_should_stop,在内核线程刚被创建并唤醒的时候,调用kthread_stop通知其退出。按照测试代码2,它应该不会主动退出的。但是实测这样是可以让内核线程退出的(甚至内核线程都没有被调度),这里没有想明白
static struct task_struct *test_task;
int test_thread(void* a)
{printk(KERN_EMERG "\r\n thread start\n");
#ifdef CONFIG_PREEMPT_COUNTprintk(KERN_EMERG "\r\n CONFIG_PREEMPT_COUNT\n");
#elseprintk(KERN_EMERG "\r\n not define CONFIG_PREEMPT_COUNT\n");
#endif while (1){/*if( kthread_should_stop()){printk(KERN_EMERG "\r\n exit while\n");break;}*/msleep(10000); }printk(KERN_EMERG "\r\n thread end\n");return 0;
}static int smsc911x_init(struct net_device *dev)
{
........................ /*timer.expires=jiffies+msecs_to_jiffies(20000);timer.function=timer_work;init_timer(&timer);add_timer(&timer);*/printk(KERN_EMERG "\r\n create thread\n");//spin_lock(&lockdep_test);test_task = kthread_create(test_thread, NULL, "test_task");wake_up_process(test_task); //task = kthread_create(kill_thread, NULL, "kill_task");kthread_stop(test_task);printk(KERN_EMERG "\r\n create thread end\n");
......................................
}
log如下:可以看到内核线程打印的thread start,并且也搜到对应的内核线程
后面有时间研究一下这个是为什么
使用注意事项
1、在执行kthread_stop的时候,目标线程必须没有退出,否则会Oops。原因很容易理解,当目标线程退出的时候,其对应的task结构也变得无效,kthread_stop引用该无效task结构就会出错。
2、内核线程的处理函数里面需要有kthread_should_stop,用于检查是否应该主动退出,否则线程是不会主动退出的。
这篇关于关于kthread_stop的疑问(linux3.16)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!