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

Linux_ fork 进程操作

2016-03-31 13:07 239 查看
什么是进程

程序的运行实例,就是“进程”

一个程序,同时执行多次,则产生多个不同的进程。

程序是静态的

进程是动态的

进程的结构

进程的组成:程序代码、数据、变量、文件描述符(表示已打开的文件)、环境等组成。

每个进程有一个唯一的编号,称为”进程标识符”(PID)

PID >= 2

PID=1的进程是init进程。

进程之间共享程序代码

即,同一个程序的多个进程,共享一个代码拷贝。

进程之间共享函数库。

进程有自己的”栈空间”、“程序计数器”、变量。

进程表

Linux把所有进程的相关信息放在一个表中,称为进程表

每个进程是一个表项。

进程表的索引,是PID

可同时运行的进程数取决于该进程表的容量。

进程的查看

ps 显示与该终端连接的进程。

ps -ef

ps ax

进程的状态

ps ax

ps的stat列表示进程的状态:

S: 睡眠,即“挂起”,等待某个事件的发生。

R: 运行

D: 不可中断的睡眠

T: 停止

Z: 死进程(僵尸进程)

s: 进程是会话期的首进程。

+:进程属于前台进程

进程的调度

单处理器上,同一个时刻只能有一个进程运行。

Linux内核用“进程调度器”来决定下一个时间片执行哪个进程。

进程的启动

1)system

实例:main7.c

在程序的内部,创建一个新进程,执行指定的shell命令。

主进程将等待新进程执行结束后,才能继续执行。
除非新进程以后台方式运行,system("ls &")

效率不高,因为要先启动shell, 然后再运行指定的shell命令。


2) exec (进程替换)

exec指一组函数.

用于:从当前进程切换到另一个程序执行,且不返回到原来的程序(除非发生了错误,返回-1)。

"l"组 (l即list, 新程序的参数为列表形式,即可变参数列表)
execl
execlp
execle

“v"组(v即vector, 新程序的参数为数组形式, 参数个数不变
execv
execvp
execve

p后缀:
第一个参数是要执行的文件名,不含路径。
文件的路径由系统默认的环境变量(path)指定。

e后缀:
最后一个参数是字符串数组,表示指定的环境变量。
注意,这个环境变量是指程序替换以后,
新程序运行期间的环境变量。
而不是替换新程序时的环境变量,
所以execle函数的第一个参数仍然需要使用路径。
替换到新程序以后,此时的环境就是execle的最后一个参数。

实例:main8.c
分别用以上六种形式,创建"ls -l"进程。

注意:
exec启动的新进程继承原进程的很多特性:
比如,原进程中打开的文件描述符,在新进程中仍保持打开。


3) fork (进程复制)

复制的新进程(子进程),与原进程一模一样,

但有自己的数据空间、环境、文件描述符等。

fork的返回值
在原进程(父进程)中,fork返回新进程(子进程)的PID
在新进程(子进程)中,fork返回0
fork失败,返回-1
失败原因:父进程能拥有的子进程数超出限制(CHILD_MAX)
进程表中的空间不足
虚拟内存不足


实例:main9.c

等待子进程结束

1) wait

功能:父进程等待任意它的任一个子进程结束

返回该结束子进程的PID

参数: 实参非空时,返回子进程的退出状态。

参见man 2 wait

实例:main10.c

2) waitpid

功能:父进程等待指定的子进程。

参数:

详见man 2 waitpid

参数3常使用WNOHANG(不阻塞,立即返回)

实例:

waitpid(child_pid, (int*)0, WNOHANG);

如果子进程未结束、未终止,则返回0

已经子进程已结束, 则返回子进程的PID

如果失败, 返回-1

僵尸进程

1) 什么是僵尸进程

僵死进程(死进程):是指该进程已经结束运行,但在进程表中还没有删除它的相关信息。

2)僵死进程产生的原因

子进程比父进程先结束,(儿子比父亲先“死”)

但是又不能在进程表中删除子进程的表项,因为父进程调用wait时还需要这些信息。

3)僵尸进程的“归宿”

子进程比父进程先结束后,成为僵尸进程。

直到父进程也结束,该僵尸进程才真正消亡(从进程表中删除其表项)

如果父进程被异常终止,则该僵尸进程认init进程为“父进程”

init进程发现该僵尸子进程后,再把它清除。

应该尽量避免产生僵尸进程。

僵尸进程虽不再运行,但仍占用系统的资源!

main11.c

测试:gcc main11.c

./a.out &

ps /* 子进程结束后 */

你知道:

for (i=0; i<2; i++) {
fork();
}


一共创建了多少个进程?
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: