一个简单的内核线程

一个简单的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()处。

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值