• Linux Kernel Development内核线程


    内核经常需要在后台执行一些操作,这种任务就可以通过内核线程(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

  • 相关阅读:
    2017-11-26 小组工作内容
    2017-11-25 小组工作内容
    2017-11-24 小组工作内容
    如何计算团队成员贡献分——1703班02组
    第一周小组博客作业——1703班02组
    2017-11-17实践作业记录
    第0次作业
    Unity3D 视频播放
    Unity3D 平滑转向
    Unity3D之Camera跟随鼠标移动,右键显示或隐藏鼠标
  • 原文地址:https://www.cnblogs.com/feisky/p/2945187.html
Copyright © 2020-2023  润新知