一、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 2017-05-22 22:19  原来是Bruce啊  阅读(221)  评论(0)    收藏  举报