当前位置: 技术问答>linux和unix
linux内核线程问题
来源: 互联网 发布时间:2014-12-19
本文导语: 我是linux内核初学者,请教大虾 内核线程和用户进程有什么区别 具体实现的流程和代码是什么啊 | 尽管linux是一个宏内核系统,但是kernel threads(内核线程)依然存在,以便并行地处理一些...
我是linux内核初学者,请教大虾
内核线程和用户进程有什么区别
具体实现的流程和代码是什么啊
内核线程和用户进程有什么区别
具体实现的流程和代码是什么啊
|
尽管linux是一个宏内核系统,但是kernel threads(内核线程)依然存在,以便并行地处理一些内核的“家务”
这些任务不占用USER memory(用户空间),而仅仅使用KERNEL memory。和其他内核模块一样,它们也在高级权限(i386系统中的RING 0)下工作作。内核线程是被kernel_thread [arch/i386/kernel/process]创建的,它又通过调用著名的clone系统调用[arch/i386/kernel/process.c] (类似fork系统调用的所有功能都是由它最终实现):
int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
{
long retval, d0;
__asm__ __volatile__(
"movl %%esp,%%esint"
"int $0x80nt" /* Linux/i386 system call */
"cmpl %%esp,%%esint" /* child or parent? */
"je 1fnt" /* parent - jump */
/* Load the argument into eax, and push it. That way, it does
* not matter whether the called function is compiled with
* -mregparm or not. */
"movl %4,%%eaxnt"
"pushl %%eaxnt"
"call *%5nt" /* call fn */
"movl %3,%0nt" /* exit */
"int $0x80n"
"1:t"
:"=&a" (retval), "=&S" (d0)
:"0" (__NR_clone), "i" (__NR_exit),
"r" (arg), "r" (fn),
"b" (flags | CLONE_VM)
: "memory");
return retval;
}
一旦调用,我们就有了一个新的任务(Task) (一般PID都很小, 例如2,3,等) 等待一个响应很慢的资源,例如swap或者usb事件,以便同步。
下面是一些最常用的内核线程(你可以用ps x命令):
PID COMMAND
1 init
2 keventd
3 kswapd
4 kreclaimd
5 bdflush
6 kupdated
7 kacpid
67 khubd
init内核线程也是启动以后最初的进程。 它会调用其它用户模式的任务,(/etc/inittab)例如控制台守护进程(daemons), tty守护进程以及网络守护进程(rc脚本)。
下面是一个典型的内核线程kswapd [mm/vmscan.c].
kswapd是被clone()建立的 [arch/i386/kernel/process.c]''
|do_initcalls
|kswapd_init
|kernel_thread
|syscall fork (in assembler)
·do_initcalls [init/main.c]
·kswapd_init [mm/vmscan.c]
·kernel_thread [arch/i386/kernel/process.c]
这些任务不占用USER memory(用户空间),而仅仅使用KERNEL memory。和其他内核模块一样,它们也在高级权限(i386系统中的RING 0)下工作作。内核线程是被kernel_thread [arch/i386/kernel/process]创建的,它又通过调用著名的clone系统调用[arch/i386/kernel/process.c] (类似fork系统调用的所有功能都是由它最终实现):
int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
{
long retval, d0;
__asm__ __volatile__(
"movl %%esp,%%esint"
"int $0x80nt" /* Linux/i386 system call */
"cmpl %%esp,%%esint" /* child or parent? */
"je 1fnt" /* parent - jump */
/* Load the argument into eax, and push it. That way, it does
* not matter whether the called function is compiled with
* -mregparm or not. */
"movl %4,%%eaxnt"
"pushl %%eaxnt"
"call *%5nt" /* call fn */
"movl %3,%0nt" /* exit */
"int $0x80n"
"1:t"
:"=&a" (retval), "=&S" (d0)
:"0" (__NR_clone), "i" (__NR_exit),
"r" (arg), "r" (fn),
"b" (flags | CLONE_VM)
: "memory");
return retval;
}
一旦调用,我们就有了一个新的任务(Task) (一般PID都很小, 例如2,3,等) 等待一个响应很慢的资源,例如swap或者usb事件,以便同步。
下面是一些最常用的内核线程(你可以用ps x命令):
PID COMMAND
1 init
2 keventd
3 kswapd
4 kreclaimd
5 bdflush
6 kupdated
7 kacpid
67 khubd
init内核线程也是启动以后最初的进程。 它会调用其它用户模式的任务,(/etc/inittab)例如控制台守护进程(daemons), tty守护进程以及网络守护进程(rc脚本)。
下面是一个典型的内核线程kswapd [mm/vmscan.c].
kswapd是被clone()建立的 [arch/i386/kernel/process.c]''
|do_initcalls
|kswapd_init
|kernel_thread
|syscall fork (in assembler)
·do_initcalls [init/main.c]
·kswapd_init [mm/vmscan.c]
·kernel_thread [arch/i386/kernel/process.c]
|
系统启动时,它运行在核心态,此时系统只有一个初始化进程(init_task)在初始化的最后,他创建并启动一个内核线程(init),然后进入空循环。当系统没有其他可以运行的进程,系统会运行此空闲进程(init_task)。init在完成必要的初始化后,开始执行用户态的初始化。当init开始执行用户态程序时它变成系统中的第一个用户进程。init根据脚本创建新的用户进程,用户进程再创建其他进程,因此系统中的所有用户进程都是内核线程(init)的后代。关系讲的应该比较清楚了。