操作系统:实验一进程控制实验

一、实验目的

1、掌握进程的概念,理解进程和程序的区别。

2、认识和了解并发执行的实质。

3、学习使用系统调用fork()创建新的子进程方法,理解进程树的概念。

4、学习使用系统调用wait()或waitpid()实现父子进程同步。

5、学习使用getpid()和getppid()获得当前进程和父进程的PID号。

6、掌握使用exec簇函数实现进程映像更换的方法。

7、了解系统编程,学习父进程如何通过创建一个子进程来完成某项特定任务的方法。

二、实验内容

1.进程的创建

编写一段程序,使用系统调用fork( )创建两个子进程,在系统中有一个父进程和两个子进程活动。让每个进程在屏幕上显示一个字符;父进程显示字符“a”,子进程分别显示字符“b” 和“c”。试观察记录屏幕上的显示结果,并分析结果。(1分)

    <参考程序>

#include<stdio.h>#include<stdlib.h>#include<unistd.h>#include<sys/types.h>int main(){   int  p1, p2;while((p1=fork())==-1);if(p1==0)printf("b ");else{   while((p2=fork())==-1);if(p2==0)printf("c ");elseprintf("a ");}return 0;}

执行结果及结果分析:

首先父进程会fork()创建一个新的子进程也就是b进程,当b进程运行到if(p1==0)语句时就会打印出“b ”,然后父进程会进入else语句,再创建一个子进程c,由于在父进程中p2>0所以进入else语句,打印“a ”,在创建出来的c进程中,p2=0打印出“c ”。

修改上题,在父进程中显示当前进程识别码,在每个子进程中显示当前进程识别码和父进程识别码,运行程序查看结果,分析运行结果。(1分)

#include<stdio.h>#include<stdlib.h>#include<unistd.h>#include<sys/types.h>int main(){   int  p1, p2;while((p1=fork())==-1);if(p1==0)    //p1子进程printf("b: pid=%d ppid=%d\n",getpid(),getppid());else       //父进程{   while((p2=fork())==-1);if(p2==0)//p2子进程printf("c: pid=%d ppid=%d\n",getpid(),getppid());else     //父进程printf("a: pid=%d\n",getpid());}return 0;}

父进程a首先创建出一个子进程p1,在p1进程中p1=0,打印出p1的pid和ppid,可以看出b的父进程为a,然后主进程运行到else语句中,再次创建一个子进程p2,在p2进程中p2=0,打印出c的pid和ppid,可以看出,c的父进程为a,主进程运行到else语句,打印出自己的pid。

改进上题,使父进程等待两个子进程结束之后再结束。(1分)

#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <sys/types.h>#include <sys/wait.h>int main() {int p1, p2;while ((p1 = fork()) == -1);if (p1 == 0) { // 子进程p1printf("b: pid=%d ppid=%d\n", getpid(), getppid());} else { // 父进程while ((p2 = fork()) == -1);if (p2 == 0) { // 子进程p2printf("c: pid=%d ppid=%d\n", getpid(), getppid());} else { // 父进程printf("a: pid=%d\n", getpid());// 等待两个子进程结束}}return 0;}

2.编写程序创建进程树如图1所示,在每个进程中显示当前进程识别码和父进程识别码。(1分)

图1进程树的参考程序:

#include<stdio.h>#include<unistd.h>int main(){int  p1,p2,p3;while((p1=fork())== -1);if(p1==0){while((p2=fork())==-1);       if(p2==0){while((p3=fork())==-1);       if(p3==0)   //p3子进程printf(" d,Mypid=%d, myppid=%d\n", getpid(), getppid());else   //p2子进程printf(" c,Mypid=%d, myppid=%d\n", getpid(), getppid());}else //p1子进程printf(" b,Mypid=%d, myppid=%d\n", getpid(), getppid());}else //主进程printf(" a,Mypid is %d\n", getpid());getchar();}

编译及执行程序:

结果截屏:

3.模仿第2题,按图2进程树编写程序,给出编译及执行过程和结果截屏。(1分)

#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <sys/wait.h>#include <sys/types.h>int main() {int p1, p2, p3, p4, p5;while ((p2 = fork()) == -1 );if(p2 > 0){waitpid(p2,NULL, 0);printf("a: pid=%d\n", getpid());while ((p4 = fork()) == -1);if(p4 == 0){waitpid(p4, NULL, 0);printf("d: pid=%d, ppid=%d\n", getpid(), getppid());while ((p5 = fork()) == -1);if(p5 == 0){waitpid(p5, NULL, 0);printf("d: pid=%d, ppid=%d\n", getpid(), getppid());}exit(0);}waitpid(p4, NULL, 0);}else if(p2 == 0){waitpid(p2, NULL, 0);printf("b: pid=%d, ppid=%d\n", getpid(), getppid());while ((p3 = fork()) == -1);if (p3 == 0) {waitpid(p3, NULL, 0);printf("c: pid=%d, ppid=%d\n", getpid(), getppid());exit(0);}waitpid(p3, NULL, 0);}return 0;}

4.分析程序,给出编译及执行过程和结果截屏。(2分)

(1)

#include<unistd.h>#include<stdlib.h>#include<stdio.h>main(){   int child,p;while((child=fork())==-1);if(child==0)    //子进程下{   printf("In child: sleep for 10 seconds and then exit. \n");sleep(10);exit(0);}else    //父进程下{   do{   p=waitpid(child,NULL,WNOHANG);  //非阻塞式等待子进程结束if(p==0){   printf("In father: The child process has not exited.\n");sleep(1);}}while(p==0);if(p==child){   printf("Get child exitcode then exit!\n");}else{   printf("Error occured!\n");}}exit(0);}

编译及执行过程和运行结果截屏:

分析程序功能:

这段程序的功能是创建一个子进程,然后父进程非阻塞地等待子进程结束。父进程调用fork()创建子进程。如果fork()成功,子进程会打印一条消息并休眠10秒,然后退出。如果fork()失败,父进程会继续尝试创建子进程,直到成功。父进程在一个循环中使用waitpid()函数以非阻塞方式等待子进程结束。这意味着父进程会定期检查子进程的状态而不会被阻塞。如果waitpid()返回0,表示子进程尚未退出,父进程会打印一条消息,并休眠1秒。循环直到waitpid()返回的进程ID等于子进程的ID,表示子进程已经退出。最后,父进程根据waitpid()返回的值来判断是否成功等待子进程退出,并打印相应的消息。综上所述,该程序实现了父进程非阻塞地等待子进程退出,并在子进程退出后打印相应的消息。

(2)

#include<unistd.h>#include<stdlib.h>#include<stdio.h>main(){   int child,p;while((child=fork())==-1);if(child==0)    //子进程下{   execl("/home/student/welcome.out","",NULL);exit(0);}else    //父进程下{   p=waitpid(child,NULL,0);  //阻塞式等待子进程结束  if(p==child)printf("Get child exitcode then exit!\n");elseprintf("Error occured!\n");}exit(0);}子进程要加载程序的源程序welcome.c:#include<stdio.h>main(){   printf("Hello! This is another process.\n");}

编译及执行过程和运行结果截屏:

分析程序功能:

这段程序的功能是创建一个子进程,然后父进程阻塞地等待子进程结束,接着根据waitpid()返回的值判断子进程是否成功退出,并打印相应的消息。父进程调用fork()创建子进程。如果fork()成功,子进程会调用execl()函数执行另一个程序/sy/sy1/welcome.out,然后子进程会退出。如果fork()失败,父进程会继续尝试创建子进程,直到成功。父进程使用waitpid()函数以阻塞方式等待子进程结束,其中参数NULL表示不获取子进程的退出状态,参数0表示等待任何子进程退出。当子进程退出后,waitpid()会返回子进程的进程ID。父进程根据waitpid()返回的值来判断是否成功等待子进程退出,并打印相应的消息。综上所述,该程序实现了父进程阻塞地等待子进程退出,并在子进程退出后打印相应的消息。

5. 编程创建2个子进程,子进程1运行指定路径下的可执行文件(如:/home/student/welcome.out),子进程2暂停10s之后退出,父进程先用阻塞方式等待子进程1的结束,然后用非阻塞方式等待子进程2的结束,待收集到二个子进程结束的信息,父进程就返回。(2分)

参考程序框架:

#include <unistd.h>#include <stdlib.h>#include <stdio.h>#include <sys/wait.h>#include <sys/types.h>int main() {int child1, child2, p;while ((child1 = fork()) == -1);if (child1 == 0) {execl("/sy/sy1/welcome.out", "", NULL);exit(0);} else {while ((child2 = fork()) == -1);if (child2 == 0) {// 子进程2暂停10秒后退出sleep(10);exit(0);} else {// 父进程等待子进程1结束p = waitpid(child1, NULL, 0);if (p == child1)printf("Get child1 exitcode then exit!\n");elseprintf("Error occurred!\n");// 父进程非阻塞方式等待子进程2结束do {p = waitpid(child2, NULL, WNOHANG);if (p == 0) {printf("In father: The child2 process has not exited.\n");sleep(1);}} while (p == 0);if (p == child2)printf("Get child2 exitcode then exit!\n");elseprintf("Error occurred!\n");}}exit(0);}

编译及执行过程:

结果截屏:

6.编写一个简易的shell解释程序。其运行原理是:当命令行上有命令需要执行时,shell进程获得该命令,然后创建子进程,让子进程执行该命令,shell进程等待子进程退出,之后继续等待命令行上的命令周而复始。(附加题)

#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <sys/wait.h>#include <string.h>#define MAX_COMMAND_LENGTH 100int main() {char command[MAX_COMMAND_LENGTH];pid_t pid;int status;while (1) {// 打印提示符printf("shell> ");// 读取命令行输入if (fgets(command, sizeof(command), stdin) == NULL) {printf("Error reading command\n");continue;}// 移除命令行输入中的换行符command[strcspn(command, "\n")] = '\0';// 创建子进程pid = fork();if (pid < 0) {perror("fork");exit(EXIT_FAILURE);} else if (pid == 0) {// 在子进程中执行命令execlp(command, command, NULL);// 如果execlp返回,说明命令执行失败perror("execlp");exit(EXIT_FAILURE);} else {// 父进程等待子进程退出waitpid(pid, &status, 0);}}return 0;}

三、实验总结和体会(1分)

通过本次实验,我学到了以下几点:

学习了如何使用fork()函数创建子进程,以及父子进程之间的关系。

理解了使用wait()和waitpid()函数等待子进程结束,并获取子进程的退出状态。

掌握了使用execl()函数在子进程中执行外部命令。

加深了对进程间通信和进程控制的理解,例如父进程等待子进程退出的过程。

熟悉了在C语言中使用系统调用来实现基本的shell解释器功能。

总的来说,通过实验,我加深了对进程管理、进程通信和操作系统底层的理解,并且了解了基本的Linux系统

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/878343.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

CentOS全面停服,国产化提速,央国企信创即时通讯/协同门户如何选型?

01. CentOS停服带来安全新风险&#xff0c; 国产操作系统迎来新的发展机遇 2024年6月30日&#xff0c;CentOS 7版本全面停服&#xff0c;于2014年发布的开源类服务器操作系统——CentOS全系列版本生命周期画上了句号。国内大量基于CentOS开发和适配的服务器及平台&#xff0c…

挂个人-CSDN Java优秀内容博主rundreamsFly抄袭

事件起因 今天点开自己的CSDN博客&#xff0c;发现给我推了一篇文章抄袭我自己昨天18点发的文章。 就是这篇&#xff0c;一字不差&#xff0c;博主昵称是&#xff1a;rundreamsFly&#xff0c;账号是rundreams。 抄袭者文章 发布于2024-8-26 19:37:41秒&#xff0c;比我发布…

CoMat——解决文本与图像之间的差异

概述 论文地址&#xff1a;https://arxiv.org/abs/2404.03653 在文本到图像生成领域&#xff0c;扩散模型近年来取得了巨大成功。然而&#xff0c;提高生成图像与文本提示之间的一致性仍然是一个挑战。 论文指出&#xff0c;扩散模型中文本条件利用不足是对齐的根本原因。论…

巧用scss实现一个通用的媒介查询代码

巧用scss实现一个通用的媒介查询代码 效果展示 实现代码 <template><div class"page-root"><div class"header"></div><div class"content"><div class"car-item" v-for"item in 9">…

K8S持久化存储数据

环境&#xff1a; Ubuntu-1:192.168.114.110作为主 Ubuntu-2:192.168.114.120作为从1&#xff0c;node节点1 Ubuntu-3:192.168.114.130作为从2&#xff0c;node节点2 持久化volumeMounts pod里面&#xff1a;emptyDir和hostPath。存储在node&#xff0c;NFS...&#xff0c;Clo…

【系统架构设计师-2015年】综合知识-答案及详解

【第1~2题】 某航空公司机票销售系统有n个售票点&#xff0c;该系统为每个售票点创建一个进程Pi&#xff08;i1&#xff0c;2&#xff0c;…&#xff0c;n&#xff09;管理机票销售。假设Tj&#xff08;j1&#xff0c;2&#xff0c;…&#xff0c;m&#xff09;单元存放某日某…

时序预测 | 基于DLinear+PatchTST多变量时间序列预测模型(pytorch)

目录 效果一览基本介绍程序设计参考资料 效果一览 基本介绍 DLinearPatchTST多变量时间序列 dlinear,patchtst python代码&#xff0c;pytorch架构 适合功率预测&#xff0c;风电光伏预测&#xff0c;负荷预测&#xff0c;流量预测&#xff0c;浓度预测&#xff0c;机械领域预…

Nginx简单的安全性配置

文章目录 引言I Nginx简单的安全性配置禁止特定的HTTP方法限制URL长度禁止某些用户代理限制请求速率连接限制禁止访问某些文件类型II 常见的安全规则防御CC攻击User-Agent过滤GET-URL过滤GET-参数过滤POST过滤(sql注入、xss攻击 )引言 Nginx本身并不具备复杂的防火墙规则定制…

笔记:应用Visual Studio Profiler识别和解决内存泄漏问题

一、目的&#xff1a;应用Visual Studio Profiler识别和解决内存泄漏问题 识别和解决内存泄漏问题是确保应用程序稳定性和性能的关键步骤。 二、实现 以下是如何使用 Visual Studio Profiler 识别和解决内存泄漏问题的详细步骤&#xff1a; 1. 启动内存分析 1. 打开项目&…

应用层(Web与HTTP)

目录 常见术语 1.HTTP概况 2.HTTP连接 非持久HTTP流程 响应时间模型 持久HTTP 3.HTTP报文 3.1HTTP请求报文 3.2HTTP响应报文 HTTP响应状态码 4.Cookies&#xff08;用户-服务器状态&#xff09; cookies&#xff1a;维护状态 Cookies的作用 5.Web缓冲&#xff08;…

私人诊所|基于SprinBoot+vue的私人诊所管理系统(源码+数据库+文档)

私人诊所管理系统 基于SprinBootvue的私人诊所管理系统 一、前言 二、系统设计 三、系统功能设计 系统功能实现 后台模块实现 管理员功能实现 患者功能实现 医生功能实现 四、数据库设计 五、核心代码 六、论文参考 七、最新计算机毕设选题推荐 八、源码获取&am…

企业级Mysql 集群技术部署

目录 1.1部署mysql 1.1.1 安装依赖性&#xff1a; 1.1.2 下载并解压源码包 1.1.3 源码编译安装mysql 1.1.4 部署mysql 2.mysql的主从复制 2.1 配置masters 2.2配置slave 2.3 延迟复制 2.4 慢查询日志 2.5并行复制 2.6 原理刨析 2. 7架构缺陷 3.半同步模式 3.1半同…

Charles苹果手机https抓包

1、电脑设置Charles代理端口 1)设置代理端口 Proxy-》Proxying Settings-》HTTP Proxy 设置端口 2)设置监控的代理地址 Proxy-》SSL Proxying Settings 添加Add允许所有地址*.* 2、电脑导入Charles的ssl证书 3、电脑查看Charles的IP地址和端口 4、手机无线wifi配置代理 5、手…

如何实现OpenHarmony的OTA升级

OTA简介 随着设备系统日新月异&#xff0c;用户如何及时获取系统的更新&#xff0c;体验新版本带来的新的体验&#xff0c;以及提升系统的稳定性和安全性成为了每个厂商都面临的严峻问题。OTA&#xff08;Over the Air&#xff09;提供对设备远程升级的能力。升级子系统对用户…

归因分析(Attribution)

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 归因1.归因是什么广告归因 2.常见的归因模型3.归因依据3.1 安卓方式3.2 IOS方式 归因 在当今纷繁复杂的数字营销环境中&#xff0c;企业面临着如何准确衡量和提升营…

1.7 离散频率

1.7 离散频率 离散时间和采样率 模拟到数字转换器 (ADC) 对连续时间信号进行采样以生成离散时间样本。对于数字信号处理器来说&#xff0c;该信号仅存储在内存中作为一系列数字。因此&#xff0c;采样率 F S F_S FS​ 的知识是数字域中信号处理的关键。 对于时间而言&#…

iPhone备忘录不小心删除了怎么办?

在日常使用iPhone的过程中&#xff0c;备忘录作为我们记录重要信息、灵感闪现和日常琐事的小帮手&#xff0c;其重要性不言而喻。然而&#xff0c;有时候因为操作失误或是不小心点击&#xff0c;我们可能会将珍贵的备忘录内容删除&#xff0c;这无疑会让人感到焦虑与不安。但请…

APP长文本内容编辑器功能实现方案

背景 CSDN APP 中原有编辑器页面为纯H5适配&#xff0c;整体用户交互体验差&#xff0c;如何优化APP端编辑器用户体验是我们团队需要思考的问题。下面我们以iOS为例展开讨论。 一、方案调研 我们分析了几款国内内容发布的APP&#xff0c;如知乎、今日头条、简书&#xff0c;…

华为海思招聘-芯片与器件设计工程师-数字芯片方向- 机试题——(共九套)(每套四十题)

华为海思招聘-芯片与器件设计工程师-数字芯片方向- 机试题-题目分享——共九套&#xff08;每套四十题&#xff09; 岗位——芯片与器件设计工程师 岗位意向——数字芯片 真题题目分享&#xff0c;完整版带答案(有答案和解析&#xff0c;答案非官方&#xff0c;未仔细校正&am…

不再畏惧猫咪浮毛,希喂、安德迈、美的宠物空气净化器性能PK

夏天来了&#xff0c;宠物换毛季加上天气闷热&#xff0c;难消的异味和漫天乱飞的猫毛双重夹击&#xff0c;家里的空气质量直线下降。还是鼻炎患者的我感到非常不适&#xff0c;有股想把家里两只毛孩子逐出家门的冲动。每天不是梳毛就是在吸毛的路上&#xff0c;猫咪们还爱到处…