一个简单的内核线程

来源:互联网 发布:杭创软件 编辑:程序博客网 时间:2024/06/02 18:11

一个简单的linux内核线程的例子,根据精通linux设备驱动上的代码整合而成。

#include <linux/module.h>#include <linux/init.h>#include <linux/sched.h>#include <linux/kthread.h>MODULE_LICENSE("GPL");static DECLARE_WAIT_QUEUE_HEAD(myevent_waitqueue); //声明了一个等待队列头,我们可以将要睡眠的进程放入本列表static struct task_struct * task_test;static int mykthread(void* unused) //内核线程实体程序{    DECLARE_WAITQUEUE(wait, current); //用本进程创建一个等待队列结点     daemonize("mykthread");   //执行线程的初始工作,然后将本线程的父线程改为kthreadd, 本线程名设为"mythread"    allow_signal(SIGKILL);      //由于daemonize默认情况下会阻止所有信号,所以如果要接收某种信号,这里要手动添加     add_wait_queue(&myevent_waitqueue, &wait);// 将本进程假如等待队列      while(true)     {          printk("<0> enter while");          set_current_state(TASK_INTERRUPTIBLE); //状态被置为TASK_INTERRUPTIBLE ,则信号唤醒进程。                                                 // 即为伪唤醒(唤醒不是因为事件的发生),因此检查并处理信号。            printk("<0> before schedule");          schedule(); //这将导致调度器从运行队列中选择一个新的任务投入运行            printk("<0> before signal_pending");          if(signal_pending(current))//判断是否有信号要处理,如果有,跳出循环,线程结束          {               break;          }             printk("<0> can trige some expand process");     }     set_current_state(TASK_RUNNING);  //将当前进程的状态设为Running     remove_wait_queue(&myevent_waitqueue, &wait);// 从等待队列中移除      return 0;}static int __init begin(void){     printk("<0> module start\n");      EXPORT_SYMBOL(myevent_waitqueue);//导出myevent_waitqueue,可以让其他程序出发      task_test = kthread_create(mykthread, NULL, "mykthread");//创建一个内核线程      if(IS_ERR(task_test))     {          return PTR_ERR(task_test);     }      wake_up_process(task_test);   //启动内核线程     printk("<0> init module end\n");     return 0;}static void __exit end(void){     printk("<0> module end\n");}module_init(begin);module_exit(end);



触发程序

#include <linux/module.h>#include <linux/init.h>#include <linux/sched.h>MODULE_LICENSE("GPL");extern wait_queue_head_t myevent_waitqueue;static int __init begain(void){     printk("<0>  trigger begain ");     wake_up_interruptible(&myevent_waitqueue);//将等待队列唤醒     return 0;}static void __exit end(void){     printk("<0> trigger end\n");}module_init(begain);module_exit(end);


这个程序的运行结果是:内核线程运行到 printk("<0> before schedule")后进入schedule(), 然后睡眠。直到触发程序加载,然后完成一次循环,停在下次循环的schedule()处。

原创粉丝点击