一、fork函数和exec族函数
1.1、fork函数
fork函数用于从已存在的进程中创建一个新进程。新进程称为子进程,而原进程称为父进程。使用fork()函数得到的子进程是父进程的一个复制品,
它从父进程处继承了整个进程的地址空间,包括进程上下文、代码段、进程堆栈、内存信息、打开的文件描述符、信号控制设定、进程优先级、进程组
号、当前工作目录、根目录、资源限制和控制终端等,而子进程所独有的只有它的进程号、资源使用和计时器等。
fork函数的代价是很大的,它复制了父进程中的代码段、数据段和堆栈里的大部分内容,使得fork函数的系统开销比较大,而且执行速度也不是很快。
1.2、fork函数语法要点
1.2.1所需头文件:
#include<sys/types.h>
#include<unistd.h>
1.2.2函数原型:
pid_t fork(void)
1.2.3函数返回值:
0,子进程
>0,父进程
- 1,出错
1.3、示例程序

1.4、程序源码
#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
int main(void){
pid_t result;
result = fork();
if(result == -1){
printf("Fork error!\n");
}
else if(result == 0){
printf("The returned value is %d\nIn child process!!\nMy PID is %d\n",result,getpid());
}
else {
printf("The returned value is %d\nIn father process!!\nMy PID is%d\n",result,getpid());
}
return result;
}
1.5、exec族函数
exec族函数提供了一个在进程中启动另一个程序执行的方法。它可以根据指定的文件名或目录找到可执行文件,并用它来取代原调用进程的数据段、
代码段和堆栈段,在执行之后,原调用进程的内容除了进程号外,其他全部被新的进程替换了。另外,这里的可执行文件即可以是二进制文件,也可以
是linux下任何可执行的脚本文件。
1.6、exec族函数成员函数的语法
1.6.1查找方式
execl、execve、execle、execlve需给出完整的文件目录路径,而execlp、execvp可以只给出文件名。
1.6.2传递参数
字母“l”的表示逐个列举参数的方式,语法为:char *arg;字母“v”的表示将所有参数整体构造指针数组传递,语法为:*const argv[]。
1.7、示例程序


1.8、程序源码
1.8.1execle的源码
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
int main(){
char *envp[] = {"PATH=/tmp","USER=david",NULL};
if (fork()==0){
if(execle("/user/bin/env","env",NULL,envp)<0){
printf("Execle error\n");
}
}
return 0;
}
1.8.2execve的源码
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
int main (){
char *arg[] = {"env",NULL};
char *envp[] = {"PATH=/tmp","USER=david",NULL};
if(fork() == 0){
if(execve("/usr/bin/env",arg,envp)<0){
printf("Execve error\n");
}
}
}
二、exit函数、_exit函数和waitpid函数
2.1exit函数和_exit函数说明
都是用来终止程序的两个函数。当程序执行到exit或_exit时,进程会无条件停止剩下的所有操作,清楚包括PCB在内的各种数据结构,并终止本程序的运行。
2.2exit和_exit函数族语法
2.2.1所需头文件:
exit:#include <stdio.h>
_exit:#include <unistd.h>
2.2.2函数原型:
exit: void exit(int status)
_exit:void _exit(int status)
2.3exit函数示例程序

2.4exit函数程序代码
#include <stdio.h>
#include <stdlib.h>
int main (){
printf("Using exit ...\n");
printf("this is the content in buffer");
exit(0);
}
2.5_exit函数示例程序

2.6_exit函数程序源码
#include <stdio.h>
#include <unistd.h>
int main (){
printf("Using exit ...\n");
printf("this is the content in buffer");
_exit(0);
}
三、wait和waitpid函数
3.1wait和waitpid函数说明:
用于父进程阻塞,直到一个子程序结束或者该进程街道了一个指定的信号为止。如果该父进程没有子进程或者它的子进程已经结束,则函数就会立即返回。
3.2waitpid函数示例程序

3.3waitpid函数函数代码
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
int main (){
pid_t pc, pr;
pc = fork();
if(pc<0){
printf("ERROR fork\n");
}
else if(pc==0){
sleep(5);
exit(0);
}
else {
do {
pr = waitpid(pc,NULL,WNOHANG);
if(pr ==0){
printf("THE child process has not exited\n");
sleep(1);
}
} while (pr ==0);
if(pr ==pc){
printf("Get child exit code: %d\n",pr);
}
else{
printf("Some error occured\n");
}
}
}
将
pr = waitpid(pc,NULL,WNOHANG);改为pr = waitpid(NULL);

四、本周总结
根据本周的实验,了解了exec函数族的一定要错误判断语句,否则会造成失败:例如:找不到文件或路径,在本周exec族函数的实验中,我的文件的目录路径使用了错误的文件目录路径导致了调用exec族函数失败,通过本周的实验已经得到了解决。
最后的自己的电脑实在是调试不出来,就在实验楼做了一下。
posted on
浙公网安备 33010602011771号