feisky

云计算、虚拟化与Linux技术笔记
  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

Linux Kernel Development----内核线程

Posted on 2013-03-05 22:30  feisky  阅读(626)  评论(0编辑  收藏  举报

内核经常需要在后台执行一些操作,这种任务就可以通过内核线程(kernel thread)完成--独立运行在内核空间的标准进程。内核线程和普通的进程间的区别在于内核线程没有独立的地址空间,mm指针被设置为NULL;它只在 内核空间运行,从来不切换到用户空间去;并且和普通进程一样,可以被调度,也可以被抢占。

实际上,内核线程只能由其他内核线程创建,在现有的内核线程中创建一个新的内核线程的方法:

1. kernel_thread      

int kernel_thread(int (*fn)(void *), void *arg, unsigned long flags);        

kernel_thread通过do_fork实现:do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0, &regs, 0, NULL, NULL)。    

需要注意的是,在执行函数fn里面必须用daemonize释放资源并挂到init下,还需要用completion等待这一过程的完成。

2. kthread_run

    struct task_struct *kthread_run(int (*threadfn)(void *data),void *data,const char *namefmt,...);

    创建内核线程并启动。    

3. kthread_create

    struct task_struct *kthread_create(int (*threadfn)(void *data),void *data, const char namefmt[], ...);

  int wake_up_process(struct task_struct *p);

    kthread_create创建一个新的内核线程,但线程是停止的,需要用wake_up_process启动它

使用示例

 1 #include <linux/kthread.h>
 2 #include <linux/module.h>
 3 
 4 #ifndef SLEEP_MILLI_SEC
 5 #define SLEEP_MILLI_SEC(nMilliSec)\
 6     do { \
 7     long timeout = (nMilliSec) * HZ / 1000; \
 8     while(timeout > 0) \
 9     { \
10     __set_current_state(TASK_INTERRUPTIBLE); \
11     timeout = schedule_timeout(timeout); \
12     } \
13     }while(0);
14 #endif
15 
16 static struct task_struct * MyThread = NULL;
17 
18 static int MyPrintk(void *data)
19 {
20     char *mydata = kmalloc(strlen(data)+1,GFP_KERNEL);
21     memset(mydata,'\0',strlen(data)+1);
22     strncpy(mydata,data,strlen(data));
23     while(!kthread_should_stop())
24     {
25         SLEEP_MILLI_SEC(1000);
26         printk("%s\n",mydata);
27     }
28     kfree(mydata);
29     return 0;
30 }
31 
32 static int __init init_kthread(void)
33 {
34     MyThread = kthread_run(MyPrintk,"hello world","mythread");
35     return 0;
36 }
37 
38 static void __exit exit_kthread(void)
39 {
40     if(MyThread)
41     {
42         printk("stop MyThread\n");
43         kthread_stop(MyThread);
44     }
45 }
46 
47 module_init(init_kthread);
48 module_exit(exit_kthread);
49 MODULE_LICENSE("Dual BSD/GPL");

参考:

http://blog.chinaunix.net/uid-20196318-id-136979.html http://blog.csdn.net/unbutun/article/details/4528407 http://blog.csdn.net/flyingcloud_2008/article/details/5857464

无觅相关文章插件,快速提升流量