概述
在Linux内核驱动里或者是其它的Linux代码里面,也会有用到线程的时候。
* Put all the gunge required to become a kernel thread without
* attached user resources in one place where it belongs.
*/
{
va_list args;
struct fs_struct *fs;
sigset_t blocked;
vsnprintf(current->comm, sizeof(current->comm), name, args);
va_end(args);
* If we were started as result of loading a module, close all of the
* user space pages. We don't need them, and if we didn't close them
* they would be locked into memory.
*/
exit_mm(current); /*释放用户空间内存*/
mutex_lock(&tty_mutex);
current->signal->tty = NULL;
mutex_unlock(&tty_mutex);
sigfillset(&blocked);
sigprocmask(SIG_BLOCK, &blocked, NULL);
flush_signals(current);
fs = init_task.fs;
current->fs = fs;
atomic_inc(&fs->count);
exit_namespace(current); /* 命名空间 */
current->namespace = init_task.namespace;
get_namespace(current->namespace);
exit_files(current);
current->files = init_task.files;
atomic_inc(¤t->files->count);
}
* Let kernel threads use this to say that they
* allow a certain signal (since daemonize() will
* have disabled all of them by default).
*/
int allow_signal(int sig)
{
if (!valid_signal(sig) || sig < 1)
return -EINVAL;
sigdelset(¤t->blocked, sig);
if (!current->mm) {
/* Kernel threads handle their own signals.
Let the signal code know it'll be handled, so
that they don't get converted to SIGKILL or
just silently dropped */
current->sighand->action[(sig)-1].sa.sa_handler = (void __user *)2;
}
recalc_sigpending();
spin_unlock_irq(¤t->sighand->siglock);
return 0;
}
#include <linux/module.h>
static pid_t thread_pid;
static struct completion thread_exited;
static int noop(void *dummy)
{
daemonize("mythread");
allow_signal(SIGTERM);
while (!signal_pending (current)) {
/* do something else */
schedule();
}
complete_and_exit(&thread_exited, 1);
}
static int test_init(void)
{
init_completion(&thread_exited);
thread_pid = kernel_thread(noop, NULL, CLONE_KERNEL | SIGCHLD);
return 0;
}
static void test_exit(void)
{
kill_proc (thread_pid, SIGTERM, 1);
wait_for_completion(&thread_exited);
}
module_init(test_init);
module_exit(test_exit);
schedule()用于进程调度, 可以理解为放弃CPU的使用权.
{
/*
* This thread doesn't need any user-level access,
* so get rid of all our resources
*/
daemonize("reported_thread");
allow_signal(SIGKILL);
do {
.......
} while(1);
complete_and_exit(&reporter_exited,0);
}
static void page_fault_seeker_exit(void)
{
....
kill_proc(pid, SIGKILL, 1);
/*kernel thread must be killed before module unloaded
*wait for the completion of kernel thread
*/
wait_for_completion(&reporter_exited);
...
}
#include <linux/kernel.h>
#include <linux/module.h>
static int noop(void *dummy)
{
int i = 0;
daemonize("mythread");
while(i++ < 5) {
printk("current->mm = %pn", current->mm);
printk("current->active_mm = %pn", current->active_mm);
set_current_state(TASK_INTERRUPTIBLE);
schedule_timeout(10 * HZ);
}
return 0;
}
static int test_init(void)
{
kernel_thread(noop, NULL, CLONE_KERNEL | SIGCHLD);
return 0;
}
static void test_exit(void) {}
module_init(test_init);
module_exit(test_exit);
这还有一个在其它内核线程中调用kernel_thread的例子。 这个的current->mm就为零了。 大部分情况, 都可以创建一个 work_queue来代替。
/*
kernel daemons & blocking mutex
March 12, 2007 - 4:27am
/******************************************************************** #include /* The resource which will be shared */ pid_t kthread_pid1 ; /*Routine for the first thread */ int kthread_routine_1(void *kthread_num) printk(KERN_INFO "Inside daemon_routine() n"); do{ set_current_state(TASK_INTERRUPTIBLE); }while(!signal_pending(current)); /*Routine for the second thread */ int kthread_routine_2(void *kthread_num) printk(KERN_INFO "Inside daemon_routine() n"); do{ set_current_state(TASK_INTERRUPTIBLE); }while(!signal_pending(current)); int _init_(void) return 0; void _fini_(void) module_init(_init_); MODULE_LICENSE("GPL");
/* |
最后
以上就是美丽故事为你收集整理的使用内核线程的全部内容,希望文章能够帮你解决使用内核线程所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复