最新消息:XAMPP默认安装之后是很不安全的,我们只需要点击左方菜单的 "安全"选项,按照向导操作即可完成安全设置。

Linux Kernel – 进程和线程的创建

XAMPP相关 中文小张 818浏览 0评论

进程和线程

先说一下进程和线程的关系,进程是系统资源分配的基本单位,线程是独立运行的基本单位。

进程是资源分配的最小单位,线程是程序执行的最小单位。

进程有自己的独立地址空间,每启动一个进程,系统就会为它分配地址空间,建立数据表来维护代码段、堆栈段和数据段,这种操作非常昂贵。而线程是共享进程中的数据的,使用相同的地址空间,因此CPU切换一个线程的花费远比进程要小很多,同时创建一个线程的开销也比进程要小很多。

线程之间的通信更方便,同一进程下的线程共享全局变量、静态变量等数据,而进程之间的通信需要以通信的方式(IPC)进行。

进程和线程的创建

新进程通过克隆父进程(当前进程)而建立fork()系统调用可用来建立新的进程(线程的创建是通过clone()系统调用)。当调用结束时,内核在内存中为新的进程分配新的PCB,父进程的PCB的内容被复制到新进程的PCB中去。
在克隆进程时,父进程和子进程共享相同的资源,包括文件、信号处理程序和进程地址空间等
不管是fork()还是clone(),最终都是调用do_fork()函数。
Linux内核线程是由kernel_thread()函数在内核态下创建的,最终调用的也是do_fork()函数。
调用API如图所示

其中do_fork()的流程如下

调用copy_process()复制父进程的进程控制块。

获得子进程的pid。

如果设置了暂停标志,则子进程的状态被设置为暂停。否则,通过唤醒函数将子进程的状态设置为就绪,并且将子进程加入就绪队列。

其中内核线程也可以叫内核任务,它们周期性执行。内核线程与普通进程之间的差别是

内核线程执行的是内核中的函数,而普通进程只有通过系统调用才能执行内核中的函数

内核线程只运行在内核态,而普通进程既可以运行在用户态也可以运行在内核态

普通进程可以使用4GB的空间,内核进程只能使用3-4GB的空间

不管是线程还是进程,亦或是内核线程,都是使用task_struct来表示它们。

进程线程相关的几个系统调用

接下来说一下与进程线程有关的系统调用,包括fork(),exec(),wait()和exit()
fork

fork()很简单,就是复制一个系统调用。当一个进程调用它时,就会出现两个几乎一模一样的进程。
fork()可能出现3个不同的返回值

父进程中,fork()返回新创建子进程的PID

子进程中,fork()返回0;

如果出错,返回一个负值

exec

执行完fork()之后,创建了一个与父进程一模一样的进程,如果需要子进程执行,就需要使用exec系统调用。
exec函数族的作用是根据指定的文件名找到可执行文件,就是在调用进程内部执行可执行文件。
如果执行成功不会返回,因为调用的实体都已经被新的内容取代。
wait

进程一旦调用了wait,就立刻阻塞自己,由wait自动分析是否当前进程的某个子进程已经退出,如果找到这么一个僵尸子进程,wait会收集这个子进程的信息,释放其PCB,并将其彻底销毁后返回,如果没有就等到有一个出现为止。
exit

exit是用来终止一个进程的,无论exit在程序中处于什么位置,只要执行到exit就陷入内核态,执行内核函数do_exit()。该函数回收与进程相关的各种内核数据结构,把其所有的子进程托付给init进程,最后调用schedule(),选择一个新的进程执行。
调用了exit之后,进程并非马上消失,而是变成僵尸状态,同时它几乎放弃了所有内核空间,但是没有释放PCB。

转载请注明:XAMPP中文组官网 » Linux Kernel – 进程和线程的创建

您必须 登录 才能发表评论!