内核线程可以用户两种方法实现:
1. 古老的方法
创建内核线程:
ret = kernel_thread(mykthread, NULL, CLONE_FS | CLONE_FILES | CLONE_SIGHAND | SIGCHLD);
内核线程方法的实现
static DECLARE_WAIT_QUEUE_HEAD(myevent_waitqueue);
rwlock_t myevent_lock;
extern unsigned int myevent_id;
static int mykthread(void *unused)
{
unsigned int event_id = 0;
DECLARE_WAITQUEUE(wait, current);
//将此线程作为kthreadd的子进程,成为一个内核线程,不占用用户资源
daemonize(“mykthread”);
//daemonize()默认阻塞所有信号,所以…
allow_signal(SIGKILL);
add_wait_queue(&myevent_waitqueue, &wait);
for ( ; ;)
{
set_current_state(TASK_INTERRUPTIBLE);
schedule();
if ( signal_pending(current) )
break;
read_lock(&myevent_lock);
if ( myevent_id)
{
event_id = myevent_id;
read_unlock(&myevent_lock);
run_umode_handler(event_id);
}
else
{
read_unlock(&myevent_lock);
}
}
set_current_state(TASK_RUNNING);
remove_wait_queue(&myevent_waitqueue, &wait);
return 0;
}
2. 现代方法(从2.6.23起)
创建内核线程更现代的方法是辅助函数kthread_create。
函数原型:
struct task_struct *kthread_create(int (*threadfin)(void *data),
void *data,
const char namefmt[],
…)
例子如下:
#include <linux/kthread.h> // kernel thread helper interface #include <linux/completion.h> #include <linux/module.h> #include <linux/sched.h> #include <linux/init.h>
MODULE_LICENSE("Dual BSD/GPL"); MODULE_AUTHOR("fuyajun1983cn@yahoo.com.cn");
struct task_struct *my_task;
/* Helper thread */ static int my_thread(void *unused) {
while (!kthread_should_stop()) {
set_current_state(TASK_INTERRUPTIBLE); schedule(); printk("I am still running/n");
}
/* Bail out of the wait queue */ __set_current_state(TASK_RUNNING);
return 0; }
/* Module Initialization */ static int __init my_init(void) { /* ... */
/* my_task = kthread_create(my_thread, NULL, "%s", "my_thread"); if (my_task) wake_up_process(my_task); */ /*kthread_run会调用kthread_create函数创建新进程,并立即唤醒它*/ kthread_run(my_thread, NULL, "%s", "my_thread");*/
/* ... */
/* ... */ return 0; }
/* Module Release */ static void __exit my_release(void) { /* ... */ kthread_stop(my_task); /* ... */ }
module_init(my_init); module_exit(my_release); |