操作系统:进程的创建(fork函数)、进程的替换(exec函数)、进程的阻塞(wait函数)、进程的终止(exit函数)、进程的挂起(sleep函数)
创始人
2024-02-11 03:05:58

文章目录

    • 1.进程的创建
    • 2.进程的替换
    • 3.进程的阻塞
    • 4.进程终止
    • 5.进程的挂起

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代码(即父进程中调用的2.2.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代码(即父进程中调用的2.2.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。

4.进程终止

①调用exit函数可以实现进程的终止;
②终止当前进程的同时不会终止该进程的所有子孙进程。孤儿进程会被init进程收养。
③使用exit函数需要引入函数库

孤儿进程示例代码

#include
#include
#includeint main(void)
{int pid;pid=fork();if(pid<0){printf("子进程创建失败!\n");}else if(pid==0){int i;for(i=0;i<10;++i){sleep(2);printf("父进程的PID=%d\n",getppid());}}else{sleep(3);printf("父进程输出自己的PID=%d\n",getpid());exit(0);}return 0;
}

运行效果:

在这里插入图片描述

5.进程的挂起

①使用sleep函数挂起一个进程;
②sleep函数的参数是需要休眠的时间,以秒计算。

相关内容

热门资讯

埃菲尔铁塔在哪 中国仿建埃菲尔... 2019年4月26日,广西南宁市,街头惊现一座巨型山寨版埃菲尔铁塔,高约20米,白色塔身,造型逼真,...
北京的名胜古迹 北京最著名的景... 北京从元代开始,逐渐走上帝国首都的道路,先是成为大辽朝五大首都之一的南京城,随着金灭辽,金代从海陵王...
苗族的传统节日 贵州苗族节日有... 【岜沙苗族芦笙节】岜沙,苗语叫“分送”,距从江县城7.5公里,是世界上最崇拜树木并以树为神的枪手部落...
应用未安装解决办法 平板应用未... ---IT小技术,每天Get一个小技能!一、前言描述苹果IPad2居然不能安装怎么办?与此IPad不...
脚上的穴位图 脚面经络图对应的... 人体穴位作用图解大全更清晰直观的标注了各个人体穴位的作用,包括头部穴位图、胸部穴位图、背部穴位图、胳...
长白山自助游攻略 吉林长白山游... 昨天介绍了西坡的景点详细请看链接:一个人的旅行,据说能看到长白山天池全凭运气,您的运气如何?今日介绍...
猫咪吃了塑料袋怎么办 猫咪误食... 你知道吗?塑料袋放久了会长猫哦!要说猫咪对塑料袋的喜爱程度完完全全可以媲美纸箱家里只要一有塑料袋的响...
demo什么意思 demo版本... 618快到了,各位的小金库大概也在准备开闸放水了吧。没有小金库的,也该向老婆撒娇卖萌服个软了,一切只...
世界上最漂亮的人 世界上最漂亮... 此前在某网上,选出了全球265万颜值姣好的女性。从这些数量庞大的女性群体中,人们投票选出了心目中最美...
苗族的传统节日 贵州苗族节日有... 【岜沙苗族芦笙节】岜沙,苗语叫“分送”,距从江县城7.5公里,是世界上最崇拜树木并以树为神的枪手部落...
北京的名胜古迹 北京最著名的景... 北京从元代开始,逐渐走上帝国首都的道路,先是成为大辽朝五大首都之一的南京城,随着金灭辽,金代从海陵王...
应用未安装解决办法 平板应用未... ---IT小技术,每天Get一个小技能!一、前言描述苹果IPad2居然不能安装怎么办?与此IPad不...
脚上的穴位图 脚面经络图对应的... 人体穴位作用图解大全更清晰直观的标注了各个人体穴位的作用,包括头部穴位图、胸部穴位图、背部穴位图、胳...