我正在学习写内核模块,在其中一个例子中,我必须确保一个线程执行了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次,那么它是在functioncleanup_moduleinit_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);
}

08-26 22:38