内核线程和普通的进程间的区别在于内核线程没有独立的地址空间,它只在 内核空间运行,从来不切换到用户空间去;并且和普通进程一样,可以被调度,也可以被抢占。
一 线程的创建
struct task_struct *kthread_createint *threadfnvoid *data, void *data, const char namefmt, . 线程创建后,不会马上运行,而是需要将kthread_create 返回的task_struct指针传给wake_up_process才能驱动线程。
也可以使用kthread_run创建线程并启动线程
struct task_struct *kthread_runint *threadfnvoid *data,void *data,const char *namefmt, .
struct task_struct *__k
kthread_createthreadfn, data, namefmt,
IS_ERR__k
wake_up_process__k
__k
可见kthread_run是在调用了kthread_create后执行了wake_up_process.
在非内核线程中调用kernel_thread,必须在调用daemonize(...)来释放资源,成为真正的内核线程,kthread_create实际调用kernel_thread但是内部已经做了处理,不需要自己调用daemonize。
二 线程的退出
kthread_stop:设置线程的退出标记(线程函数内应用int kthread_should_stop(void)函数,当返回真时应退出函数),kthread_stop会一直等待至线程结束,线程结束前会发送完成结束给kthread_stop,如果直接使用do_exit直接退出线程那么kthread_stop不会收到完成信号将一直等待下去。如果线程已经退出那么kthread_stop会先设置退出标记再唤醒一下thread,唤醒线程后会判断退出标记因此设定的处理函数不会被调用。如果线程已经被唤醒并已经退出那么kthread_stop会一直等待。
int kthread_stopstruct task_struct *thread 如果处理函数没用kthread_should_stop判断退出,那么 kthread_stop会一直等待处理函数主动退出。
三 内核线程例程
触摸屏驱动中,内核线程的一个例程。
开启线程:
i2c.thread kthread_createilitek_i2c_polling_thread, NULL, ifi2c.thread struct task_struct*ERR_PTR
i2c.thread NULL
printkILITEK_ERROR_LEVEL , __func__
else
wake_up_processi2c.thread
线程函数:
static int i2c_polling_threadvoid *arg int
// mainloop
while
// check whether we should or not
ifkthread_should_stop
// this delay will influence the CPU usage and response latency
msleep
// when i2c is or mode, we nothing
ifi2c.stop_polling
msleep
// i2c data
ifilitek_i2c_process_and_report
msleep
printkILITEK_ERROR_LEVEL , __func__
printkILITEK_DEBUG_LEVEL , __func__
ret
kthread_should_stop()会去判断是不是有某人调用了kthread_stop去终止你的内核线程,如果是就会退出无限循环, 然后内核会通知kthread_stop,表明线程退出了,kthread_stop函数等到线程退出后才会返回。
还没有评论,来说两句吧...