2015-09-10 3 views
0

Я учусь писать модули ядра, и в одном из примеров я должен был убедиться, что поток выполняется 10 раз и выходит, поэтому я написал это в соответствии с тем, что я изучил:Linux - Control Flow в модуле ядра linux

#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"); 

то, что я хочу знать: а) Как сделать нить выполнить 10 раз, как цикл б) Как потоки управления в такого рода процессах, то есть если мы делаем это, чтобы выполнить 10 раз то происходит ли оно взад и вперед между function и cleanup_module или init_module или что именно происходит?

ответ

2

Если вы контролируете KTHREAD с kthread_stop, то KTHREAD должны не выйти, пока будет остановлен рый (см также, что answer). Итак, после выполнения всех операций, kthread должен дождаться остановки.

Ядро уже реализует механизм kthread_worker, когда kthread просто выполняет работы, добавленные к нему.

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); 
} 
Смежные вопросы