教程进程序开发.pptx
第6章多进程程序开发
;了解进程的概念
掌握多进程程序的设计方法
掌握fork函数和execve函数的特性和使用方法;实验1:利用fork创建进程
实验2:连续调用多次fork函数
实验3:启动外部程序
;实验目的
掌握fork函数的特性和使用方法
实验内容
请读者实现本节fork函数示例程序代码,体会进程的创建过程;原理/背景
进程是程序的一次执行
程序本身不是进程,只是被动实体,如存储在磁盘上的文件内容
进程是一个动态的概念,是一个活动的实体
进程不只是程序代码,还包括通过程序计数器的值和CPU寄存器内容表示的当前活动;原理/背景
进程在执行过程中,可以通过系统调用的方式创建多个新进程
Linux系统提供了两种创建进程的方式
函数fork()用来创建一个新的进程,该进程几乎是当前进程的一个完全拷贝
函数族exec()用来启动另外的进程以取代当前运行的进程;原理/背景
fork在英语中有“分叉”的含义
在Linux或Unix系统中,一个进程在运行时,如果使用了fork,就产生了另一个与之几乎完全相同的进程,于是进程就“分叉”了;原理/背景
fork函数说明
fork函数原型:pid_tfork(void);
头文件:unistd.h
功能:fork函数通过系统调用创建一个与原来进程几乎完全相同的进程,也就是说两个进程可以做完全相同的事,但如果初始参数或者传入的变量不同,两个进程也可以做不同的事。若成功调用一次则返回两个值,子进程返回0,父进程返回子进程ID;否则,出错返回-1;原理/背景
两个在进程相关程序中常用到的函数
getpid
函数原型:pid_tgetpid(void);
头文件:unistd.h
功能:返回当前进程的标识
getppid
函数原型:pid_tgetppid(void);
头文件:unistd.h
功能:返回父进程的标识;关键说明
fork函数创建的子进程和父进程的区分
本质来说,fork函数启动一个新的进程,这个进程几乎是当前进程的一个拷贝:子进程和父进程使用相同的代码段;子进程复制父进程的堆栈段和数据段
子进程一旦开始运行,虽然它继承了父进程的一切数据,但实际上数据却已经分开,相互之间不再有影响了,也就是说,它们之间不再共享任何数据
它们再交互信息时,只有通过进程间通信来实现;关键说明
fork函数创建的子进程和父进程的区分
对于父进程,fork函数返回了子程序的进程号,而对于子程序,fork函数则返回零
在Linux系统中,用getpid函数就可以看到不同的进程号,对父进程而言,它的进程号是由比它更低层的系统调用赋予的,而对于子进程而言,它的进程号即是fork函数对父进程的返回值;实验目的
理解进程间的创建关系
实验内容
请读者验证实现本节多次调用fork函数的示例程序,体会多进程程序中进程间的父子关系;原理/背景;原理/背景;实验目的
掌握execve函数的使用方法,理解execve函数启动外部程序的特性
实验内容
请读者验证实现execve函数的示例程序,体会execve函数的执行特性;原理/背景
若在程序中启动一个外部程序,需要使用execve()系统调用
完整定义为
intexecve(constchar*filename,char*constargv[],char*constenvp[]);
该系统调用会执行名称为filename的二进制程序或脚本程序。需要注意的是,filename必须是程序的完整路径。后面两个参数argv和envp分别表示传递给执行文件的指针数组和新环境变量数组,argv和envp两个数组必须以NULL作为最后一个数组元素;原理/背景
与fork函数不同的是,execve只有在调用失败的时候才有返回值。在调用成功后,新启动的程序与当前进程融为一体了。新启动的外部程序退出,当前进程也退出。也就是说,在execve()后面的代码不会被执行;拓展
execve()这种将其启动的程序与当前进程合并的现象,在绝大多数情况下都不是所期望的结果。最起码在执行完外部程序之后,还希望程序能够继续执行下去
要解决这个问题,可以借助于fork()函数,在新建的子进程中执行execve(),然后程序就可以继续做别的事情了;课后练习
在启动外部程序示例代码基础上,修改代码使得它能够启动外部程序的同时能够正常输出后续的语句