一、知识点
1.创建进程fork()
#include <unistd.h>
pid_t fork(void);
函数功能:
创建进程;函数执行后,系统会创建一个与原进程几乎相同的进程,之后父子进程都继续执行.
返回值:
负值:创建子进程失败
0:返回到新创建的子进程
正值:返回父进程或者调用者。包含新创建得子进程的ID号
2.wait()
#include <sys/types.h>
#include <sys/wait.h>
pid_t wait(int *wstatus);//wstatus是传出参数,
函数功能:
父进程调用wait函数可以回收子进程的终止信息。
1.阻塞等待子进程退出
2.回收子进程残留资源
3.获取子进程结束状态(推出原因)
返回值:
-1:失败,没有子进程
子进程ID:成功,返回清理掉的子进程
3.exit()
#include <unistd.h>
void exit(int status);
功能:
当程序执行到exit或_exit时,系统无条件的停止剩下所有操作,清除包括PCB(进程控制块)在内的各种数据结构,并终止本进程的运行。
二、代码实现
1.创建单个进程
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main(){
pid_t tempPid;
tempPid = fork();
if(tempPid == -1){
perror("fork error");
}else if(tempPid > 0){//parent
printf("parent process, pid = %d, ppid = %d\n", getpid(), getppid());
}else{//child
printf("child process, pid = %d, ppid = %d\n", getpid(), getppid());
}//of if
printf("......finish......");
return 0;
}//of main
运行截图:
2.创建多个进程
利用for循环实现
int i;
for(i = 0; i < 2; i ++){
tempPid = fork();
}
每一次for循环的进程数都是当前进程数量的两倍,两次循环就是4个进程。
代码实现:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main()
{
pid_t temppid;
int i;
for(i = 0;i<5;i++){ //创建循环进程
if((temppid=fork()) == 0) //若当前进程为子进程,便跳出循环
break;
}//of for i
if(temppid == -1){ //创建失败
perror("fork error");
exit(1); //退出进程,指定返回值1
}
else if(temppid>0){ //父进程
printf("parent processe,pid = %d",getpid());
}
else if(temppid == 0){ //创建成功子进程
printf("I am child = %d,pid = %d\n",i+1,getpid());
}//of if
printf("...........finished........\n");
return 0;
}//of main
运行截图:
代码执行后发现:终端提示符后面还在继续输出子进程信息,且进程编号乱序
原因:子进程被创建之后,和父进程以及其他进程竞争CPU,同时Shell命令行也是一个进程,与新建进程一起竞争CPU。所以他们的执行顺序是不确定的,终止的顺序也不确定。
解决办法:使用sleep()函数,暂缓进程执行
解决顺序问题后的代码:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main()
{
pid_t temppid;
int i;
for(i = 0;i<5;i++){ //创建循环进程
if((temppid=fork()) == 0) //若当前进程为子进程,便跳出循环
break;
}
if(temppid == -1){ //创建失败
perror("fork error");
exit(1); //退出进程,指定返回值1
}
else if(temppid>0){ //父进程
sleep(5);
printf("parent processe,pid = %d",getpid());
}
else if(temppid == 0){ //创建成功子进程
sleep(1);
printf("I am child = %d,pid = %d\n",i+1,getpid());
}
printf("...........finished........\n");
return 0;
}
运行截图:
总结
通过这次课程学习了建立子进程的方法,并且解决了相关问题,通过代码实践更好的掌握了知识点。