操作系统:进程的创建(fork函数)、进程的替换(exec函数)
创始人
2024-02-10 02:10:06
0

文章目录

    • 1.进程的创建
    • 2.进程的替换
    • 3.进程的阻塞

1.进程的创建

①调用fork函数的进程为父进程,调用后生成一个子进程;
②创建子进程成功时,父进程中fork函数的返回值是子进程的进程号PID;
③创建子进程失败时,父进程中fork函数的返回值是一个负数;
④子进程复制当前进程中所有变量的值,并复制fork函数调用后父进程剩下的所有代码。
⑤子进程中的进程号PID为0。
⑥需要引入头文件

另外,可以用getpid函数获取当前进程的进程号PID

Current_Pid=getpid()

问题举例:

编写程序,使用系统调用fork()创建如下的进程树,当此程序运行时,在系统中有一个父进程和多个子进程活动,父进程等子进程运行结束后退出。
每个进程循环5次显示不同的字符串。假设X的初值为2022,父进程的字符串内容包括自己的学号、姓名、变量X的值;子进程字符串包括进程PID、子进程序号(子进程1或2)、变量X的值。每次循环X的值加5。记录屏幕上的显示结果,并分析变量X的变化规律。
在这里插入图片描述

求解代码:

#include
#include  //使用fork函数和getpid函数都需要导入这个头文件int main(void)
{int pid1,pid2;  //分别用两个变量记录两个子进程的进程号int x=2022;    int temppid;   //记录某时刻的进程号pid1=fork();   //父进程用fork函数创建一个新的子进程if(pid1<0)     //如果子进程的进程号小于1则表示进程创建失败{printf("第一个子进程创建失败!\n");}else if(pid1==0)  //如果进程号为0表示当前进程就是第一个子进程,则执行下面的代码段{pid2=fork(); //创建一个新的子进程if(pid2<0)    //创建第二个子进程失败的情况{printf("第二个子进程创建失败!\n");}else if(pid2==0)  //第二个子进程执行的代码段{int k=0;for(k=0;k<5;++k){temppid=getpid();printf("PID=%d 串联创建的子进程2  X=%d\n",temppid,x);x+=5;}}else //第一个子进程执行的代码段{int j=0;for(j=0;j<5;++j){temppid=getpid();printf("PID=%d 串联创建的子进程1  X=%d\n",temppid,x);                                                                                                                                                                                                                                                                      x+=5;}}}else  //父进程执行的代码段{int i=0;for(i=0;i<5;++i){temppid=getpid();printf("学号:123 姓名:小明 X=%d\n",x);x+=5;}}return 0;
}

运行效果:

在这里插入图片描述

2.进程的替换

①调用execlp函数可以进行进程替换;
②execlp函数的参数是需要执行的带有完整路径的程序名以及一个指针(注意是可执行文件而不是源代码C文件,指针一般取NULL);
③进程替换后该进程的数据区和代码区都变为替换到的程序的数据和代码。

问题举例:

修改上一题编写的程序,将子进程改为独立的程序,父进程创建子进程并进行程序替换,观察程序执行时屏幕出现的现象,并分析原因。

求解代码:

①父进程代码:

#include
#includeint main(void)
{int pid1,pid2;int x=2022;int temppid;pid1=fork();if(pid1<0){printf("子进程1创建失败!\n");}else if(pid1==0){pid2=fork();if(pid2<0){printf("第二个子进程创建失败!\n");}else if(pid2==0){execlp("./2.2.2",0);}else{execlp("./2.2.1",0);}}else{wait(NULL);int i=0;for(i=0;i<5;++i){temppid=getpid();printf("学号:123 姓名:小明 X=%d\n",x);x+=5;}}return 0;
}

②子进程1代码:

#include
#includeint main(void)
{int x=2022;int i;int pid;for(i=0;i<5;++i){pid=getpid();printf("PID=%d 子进程1  X=%d\n",pid,x);x+=5;}return 0;
}

③子进程2代码:

#include
#includeint main(void)
{int x=2022;int i;int pid;for(i=0;i<5;++i){pid=getpid();printf("PID=%d 子进程2  X=%d\n",pid,x);x+=5;}return 0;
}

运行效果:

在这里插入图片描述

3.进程的阻塞

①调用wait函数可以实现进程的阻塞;
②调用wait函数的进程必须等到其所有子进程结束后才能继续执行;
③wait函数的参数为一个指针,一般传入NULL。

相关内容

热门资讯

喜欢穿一身黑的男生性格(喜欢穿... 今天百科达人给各位分享喜欢穿一身黑的男生性格的知识,其中也会对喜欢穿一身黑衣服的男人人好相处吗进行解...
发春是什么意思(思春和发春是什... 本篇文章极速百科给大家谈谈发春是什么意思,以及思春和发春是什么意思对应的知识点,希望对各位有所帮助,...
网络用语zl是什么意思(zl是... 今天给各位分享网络用语zl是什么意思的知识,其中也会对zl是啥意思是什么网络用语进行解释,如果能碰巧...
为什么酷狗音乐自己唱的歌不能下... 本篇文章极速百科小编给大家谈谈为什么酷狗音乐自己唱的歌不能下载到本地?,以及为什么酷狗下载的歌曲不是...
华为下载未安装的文件去哪找(华... 今天百科达人给各位分享华为下载未安装的文件去哪找的知识,其中也会对华为下载未安装的文件去哪找到进行解...
家里可以做假山养金鱼吗(假山能... 今天百科达人给各位分享家里可以做假山养金鱼吗的知识,其中也会对假山能放鱼缸里吗进行解释,如果能碰巧解...
四分五裂是什么生肖什么动物(四... 本篇文章极速百科小编给大家谈谈四分五裂是什么生肖什么动物,以及四分五裂打一生肖是什么对应的知识点,希...
怎么往应用助手里添加应用(应用... 今天百科达人给各位分享怎么往应用助手里添加应用的知识,其中也会对应用助手怎么添加微信进行解释,如果能...
客厅放八骏马摆件可以吗(家里摆... 今天给各位分享客厅放八骏马摆件可以吗的知识,其中也会对家里摆八骏马摆件好吗进行解释,如果能碰巧解决你...
美团联名卡审核成功待激活(美团... 今天百科达人给各位分享美团联名卡审核成功待激活的知识,其中也会对美团联名卡审核未通过进行解释,如果能...