#include <linux/module.h>
#include <linux/version.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/jiffies.h>
#include <linux/delay.h>
//这三个头文件与内核线程的使用有关;
#include <linux/sched.h> //wake_up_process()
#include <linux/kthread.h> //kthread_create(),kthread_run()
#include <linux/err.h> //IS_ERR(),PTR_ERR()
MODULE_LICENSE("GPL");
MODULE_AUTHOR("*************");
MODULE_VERSION("2.6.35.000");
//STEP5:实现线程函数
static int thread_process(void* param)
{
unsigned long t1 = 0, t2 = 0;
while(1)
{
set_current_state(TASK_UNINTERRUPTIBLE);
//当前线程是否需要停止;1-YES; 0-NO;当对该线程调用过kthread_stop()函数之后,函数kthread_should_stop()就会返回1;
if(kthread_should_stop())
{
printk("kernel thread should stop;file:%s;line:%d\n", __FILE__, __LINE__);
break;
}
t1 = jiffies;
/*
sleep 1 second; HZ=100次/1s=100次/1000ms;物理意义就是:每秒钟产生100次时钟滴答/时钟中断;
而mdelay()函数参数的单位是ms;
*/
mdelay(10*HZ);
t2 = jiffies;
printk("HZ = %d, t1 = %lu, t2 = %lu, t2 - t1 = %lu\n", HZ, t1, t2, (t2 - t1));
}
return 567; //这个返回值将通过do_exit(567)函数传递给函数kthread_stop(),然后,函数kthread_stop()再把这个返回值返回给调用者;
};
//STEP1:定义一个内核线程对象
static struct task_struct* my_thread = NULL;
static int __init study_init(void)
{
int err = 0;
printk("%s\n", __PRETTY_FUNCTION__);
//STEP2:创建并初始化一个内核线程my_thread,但是这个内核线程my_thread并不会立即开始运行;
my_thread = kthread_create(thread_process, NULL, "my_thread");
if(IS_ERR(my_thread))
{
err = PTR_ERR(my_thread);
my_thread = NULL;
printk(KERN_ERR "unable to start kernel thread:%d\n", err);
return err;
}
//STEP3:唤醒并开始运行刚刚创建的内核线程my_thread;
wake_up_process(my_thread);
printk("kernel thread start;file:%s;line:%d\n", __FILE__, __LINE__);
return 0;
}
static void __exit study_exit(void)
{
int ret = -1;
printk("%s\n",__PRETTY_FUNCTION__);
//STEP4:停止内核线程my_thread;
if(my_thread)
{
ret = kthread_stop(my_thread); //函数kthread_stop()会把线程函数int thread_process(void* param)的返回值返回给调用者;
my_thread = NULL; //线程停止之后,要把线程句柄置空;
}
printk("kernel thread stop,exit code is %d;file:%s;line:%d\n",ret, __FILE__, __LINE__);
}
module_init(study_init);
module_exit(study_exit);
注意:
1、kthread_create()创建线程之后,线程是处于休眠状态,并不会立即运行,需要使用wake_up_process()唤醒并调度运行该线程;
2、在调用kthread_stop()函数时,必须保证线程函数不能已经运行结束(即:必须保证线程函数任然在运行),否则,kthread_stop()函数会一直等待下去;kthread_stop()函数通过发送信号给线程,使之退出;另外,在线程函数中也可以通过调用do_exit()函数来结束线程;
3、线程函数必须能够让出CPU,以便让其它线程运行;同时,线程函数也必须能够被重新调度运行;可通过调用函数schedule_timeout(HZ)函数来进行重新调度的;
联系客服