当前位置: > Linux教程 > Linux学习 >

Linux下内核进程、用户进程和轻量级进程(LWP)的理解

时间:2019-05-28 14:03来源:linux.it.net.cn 作者:IT
区别和联系
我们经常提到线程、线程组、内核进程、用户进程、轻量级进程等词汇,那么他们之间有什么区别和联系呢?

首先,我们需要明确一点,Linux下并没有真正意义上的线程,甚至可以说没有进程这个概念,Linux下只有task,其对应的数据结构为task_struct,这里为了方便说明以及按照比较主流的说法,我们将task称之为进程。

对于一个进程来说,它一定是运行在内存的某个连续或不连续的区域,先以用户进程为例。

用户进程和内核进程
对于Linux来说,有两个概念叫做内核空间和用户空间,以32位x86架构的Linux为例,Linux的虚拟地址空间为4GB,其中前1GB称为内核空间,后3GB称为用户空间,进程运行在内核空间时称为内核态,运行在用户空间称之为用户态。对于用户态进程来说,出于程序设计方便和内存安全的角度等原因,为每个用户态进程引入了独立的虚拟地址空间,其被映射到用户空间。

用户进程,平时运行在用户态,有自己的虚拟地址空间,但是可以通过中断、系统调用等内陷到内核态。
内核进程,没有独立的地址空间,所有内核线程的地址空间都是一样的,没有自己的地址空间,所以它们的”current->mm”都为空,其运行在内核空间,本身就是内核的一部分或者说是内核的分身。

线程、轻量级进程、线程组和用户进程
我们开始说到,linux下没有真正意义上的线程,那么linux下的线程是什么呢?

我们说过Linux下只有task,对应的数据结构为task_struct,task_strcut中就包含了task所拥有的各种资源,如果一个运行在用户空间的task独占task_struct的所有资源,我们说它是一个用户进程,当若干个task要共享资源时,我们把这些task称之为LWP(轻量级线程)。

Linux的线程只是共享了资源的进程,所以在Linux下,线程其实就是LWP,而那些共享了资源的task组合在一起,我们称之为线程组。

即对于普通的用户进程,我们可以认为是只有一个LWP的线程组,但对于一个有着多线程的进程(线程组),其中的每一个线程都是LWP,组内共享资源。在一个普通进程内创建线程时,就是在线程组内增加LWP。

进程的创建
在Linux下,有着这几个创建进程(task)的函数:
fork
vfork
clone
pthread_create
kernel_thread
所有的这些函数,最终都是在调用do_fork(),只是传入的参数不同

fork(sys_fork)在调用do_fork()时,clone_flags没有置位任何clone标志位,即创建的进程不共享任何数据。
vfork(sys_vfork)在调用do_fork()时,置为了CLONE_VFORK CLONE_VM,即共享VM,以及当mm_release时子进程唤醒父进程
clone(sys_clone)本身只进行clone_flags的传递
pthread_create 则将CLONE_VM CLONE_FS CLONE_FILES CLONE_SIGHAND等标志位置位,即共享VM,共享fs info,共享打开的文件,共享信号句柄和阻塞的信号? 即除了栈是独立的,其他都是共享的,所以在linux中,线程仅仅是一个使用共享资源的轻量级进程
kernel_thread 在传递的参数基础上增加了CLONE_VM和CLONE_UNTRACED。
kernel_thread 只能由内核进程调用,创建的进程没有独立虚拟地址空间,只能运行在内核空间,为内核进程。
fork,创建的进程与父进程不共享资源,而是写时复制,故而创建的是用户进程
vfork,带有CLONE_VM标志位,故而创建的是LWP
pthread_create,共享各类资源,创建的也是LWP
关于fork vfork clone pthread_create kernel_thread 以及 do_fork更进一步的细节,先挖个坑,以后再填


(责任编辑:IT)
------分隔线----------------------------