exec用被执行的程序替换调用它的程序。
区别:
fork创建一个新的进程,产生一个新的PID。
exec启动一个新程序,替换原有的进程,因
此进程的PID不会改变。
exit()和_exit()的区别可以参考该篇博客
well,接下来就是wait函数和sleep函数的用法
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <math.h>
int main(void)
{
pid_t child;
/* 创建子进程顺便判断是否失败 */
if((child=fork())==-1)
{
printf("Fork Error : %s\n", strerror(errno));
exit(1);
}
else
if(child==0) // 子进程
{
printf("the child process is run\n");
sleep(1); //子进程睡眠一秒,但并没有去运行父进程
printf("I am the child: %d\n", getpid());
exit(0);
}
else //父进程
{
wait(NULL); //等到子进程退出,父进程才会运行
printf("the father process is run\n");
printf("I am the father:%d\n",getpid());
return 0;
}
}
运行结果如下:
the child process is run
I am the child: 4936
the father process is run
I am the father:4935
这里,虽然使用的是fork创建进程,父子进程调用顺序无法确定,但是,使用了wait函数,及时先调用的是父进程,也会进入阻塞态,直到子进程结束后方可执行,这就是wait函数的用法
wait()等待任一僵死的子进程,将子进程的退出状态(退出值、返回码、返回值)保存在参数status中。即进程一旦调用了wait,就立即阻塞自己,由wait分析是否当前进程的某个子进程已经退出,如果找到这样一个已经变成僵尸的子进程,wait就会收集这个子进程的信息,并把它彻底销毁后返回;如果没有找到这样一个子进程,wait就会一直阻塞在这里,直到有一个出现为止。若成功,返回该终止进程的PID;否则返回-1。
waitpid()函数的使用方法
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
pid_t pid;
pid = fork();
if (pid < 0)
{
perror("fork failed");
exit(1);
}
if (pid == 0)
{
int i;
for (i = 3; i > 0; i--)
{
printf("This is the child\n");
sleep(1);
}
exit(3);
}
else
{
int stat_val;
waitpid(pid, &stat_val, 0);
if (WIFEXITED(stat_val))
printf("Child exited with code %d\n", WEXITSTATUS(stat_val\
));
}
return 0;
}
waitpid()等待标识符为pid的子进程退出,将该子进程的退出状态(退出值、返回码、返回值)保存在参数status中。参数options规定调用的行为,WNOHANG表示如果没有子进程退出,立即返回0;WUNTRACED表示返回一个已经停止但尚未退出的子进程信息。
waitpid(pid, &stat_val, 0)会阻塞父进程等待pid指定的子进程退出,此时CPU空闲,系统会调度子进程执行,显示三次字符串“This is the child”, 退出status为3,子进程结束后唤醒父进程,显示Child exited with code 3。
**getpid()返回调用该系统调用的进程的id
号,getppid()返回调用该系统调用的进程父进程
的id号。**
系统调用sleep用来使进程主动进入睡眠状态,该函数的一般形式是:
sleep(秒数);
执行该系统调用后,进程将进入睡眠状态,直到指定的秒数已到。正常情况下,该调用的返回值为0.