我正在学习写内核模块,在其中一个例子中,我必须确保一个线程执行了10次并且退出,所以我根据我研究的内容编写了:
#include <linux/module.h>
#include <linux/kthread.h>
struct task_struct *ts;
int flag = 0;
int id = 10;
int function(void *data) {
int n = *(int*)data;
set_current_state(TASK_INTERRUPTIBLE);
schedule_timeout(n*HZ); // after doing this it executed infinitely and i had to reboot
while(!kthread_should_stop()) {
printk(KERN_EMERG "Ding");
}
flag = 1;
return 0;
}
int init_module (void) {
ts = kthread_run(function, (void *)&id, "spawn");
return 0;
}
void cleanup_module(void) {
if (flag==1) { return; }
else { if (ts != NULL) kthread_stop(ts);
}
return;
}
MODULE_LICENSE("GPL");
我想知道的是:
a)如何使线程像循环一样执行10次
b)在这种过程中,控制是如何流动的,即如果我们让它执行10次,那么它是在
function
和cleanup_module
或init_module
之间来回流动,还是具体发生了什么? 最佳答案
如果用kcType控制cth>,kT线不应该退出直到停止(也见answer)。因此,在执行完所有操作之后,kthread应该等到停止。
内核已经实现了kthread_stop
机制,当kthread只是执行works时,添加到其中。
DEFINE_KTHREAD_WORKER(worker);
struct my_work
{
struct kthread_work *work; // 'Base' class
int n;
};
void do_work(struct kthread_work *work)
{
struct my_work* w = container_of(work, struct my_work, work);
printk(KERN_EMERG "Ding %d", w->n);
// And free work struct at the end
kfree(w);
}
int init_module (void) {
int i;
for(i = 0; i < 10; i++)
{
struct my_work* w = kmalloc(sizeof(struct my_work), GFP_KERNEL);
init_kthread_work(&w->work, &do_work);
w->n = i + 1;
queue_kthread_work(&worker, &w->work);
}
ts = kthread_run(&kthread_worker_fn, &worker, "spawn");
return 0;
}
void cleanup_module(void) {
kthread_stop(ts);
}