您的位置:首页 > 运维架构 > Linux

关于Linux多进程

2013-05-08 23:56 85 查看
今天看了《Linux高级程序设计》中有关进程的部分,在这里仅写一下自己的理解,望大家多多指教。总体感觉跟Windows上的进程不太一样,初次学习时甚至搞不懂程序是怎么运行的,其中最让我不能理解的是父、子进程竟然在一个函数中运行。其中有这样一个例子:

int main(void)

{

pid_t pid = fork();

if (pid == -1)

{

printf("fork error");

}

else if (pid == 0)

{

printf("in the child process");

}

else

{

printf("in the parent process");

}

return 0;

}

在上面的程序中,通过fork函数创建了一个进程,但并没有像Windows程序中通过CreateProcess创建进程那样启动另外一个新的程序,而是在fork后开始有两个进程在运行同一份代码,上面程序只是通过fork的返回值判断该运行父进程还是子进程的代码。之前在Linux的多进程时,就被这一点给弄糊涂了,硬是没搞懂程序是怎么运行的,通过亲手编写代码测试后才真正理解这是怎么一回事。

在fork函数之前,只有一个进程(即父进程)在运行,当调用fork成功后,就会出现新的进程(即子进程)从fork的下一句代码开始执行,而父进程则继续原来的执行,也是fork的下一句代码。fork只是创建的一个进程,无法控制该进程去执行特定的代码,所以在程序中通常通过fork的返回值来判断下一步该执行什么操作。在父进程中,fork将返回新创建的子进程的PID,而在子进程中,这个返回值为0。子进程创建成功后,会复制父进程的几乎所有信息,包括副进程的代码段、数据段、堆、栈以及PCB等信息。我的理解是,栈中在fork函数之前的所有数据在父子进程中都是相同的,从fork开始,即fork的返回值,父子进程就拥有了各自独立的进程空间了。对于一些内核对象的句柄,如打开的文件、SOCKET、管道等,同样会复制到子进程中,而且父子进程中的句柄指向内核中相同的对象,对于文件,它们共享文件指针、偏移、权限等,且在父子进程中需要分别关闭这些句柄。这些特性是在Windows上使用CreateProcess无法做到的。

另外,Linux提供了exec系列的函数,如execl、execp等,它们用来在进程中运行新代码,即运行其他的程序,这一点似乎和Windows的CreateProcess相同。但是,CreateProcess是创建一个新的进程来运行新程序,可以选择等待新进程退出或继续执行本程序代码。而exec系列函数并不创建新进程,而仅仅将新程序的资源加载到内核中并执行新的代码,新程序的代码运行结束后才会回到原有程序继续执行,即exec函数的下一句代码。如果要实现CreateProcess类似的功能,则需要使用fork函数创建一个新进程,然后在子进程中调用exec系列函数执行新的程序。

进程退出后,会自动释放用户控件的所有资源,如执行退出处理函数、刷新流缓冲区等,但是进程内核控件的资源,如PCB,并没有释放,它只能由父进程完成,在父进程中调用wait、waitpid等待所有或指定进程退出,并回收子进程的内核进程资源。如果父进程比子进程早退出,那么子进程的父进程会更改为系统的init进程,它会在子进程退出时回收子进程的内核空间资源。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  Linux fork 多进程