操作系统导论-课后作业-ch5

关于man的使用

man  系统参考手册
man n name   在系统手册第n章查看name

1.

代码:

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/wait.h>int main() {int x = 100;int rc = fork();if (rc == -1) {fprintf(stderr, "fork failed\n");} else if (rc == 0) {printf("child pid: x = %d\n", x);} else {wait(NULL);}return 0;
}

输出:
在这里插入图片描述
子进程会保持和父进程一样的值100,当子进程和父进程都改变x的值时,变量会各自单独保持一份互不影响,相互隔离。

2.

#include <stdio.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>int main(int argc, char* argv[]) {int fd = open("./tmp.txt", O_CREAT | O_APPEND | O_RDWR, S_IRWXU);int rc = fork();if (rc == -1) {fprintf(stderr, "fork failed\n");} else if (rc == 0) {int i;for (i = 0; i < atoi(argv[1]); i++) write(fd, "child\n", 6);} else {int i;for (i = 0; i < atoi(argv[1]); i++) write(fd, "parent\n", 7);wait(NULL);close(fd);}return 0;
}

结果如下:
在这里插入图片描述
1次并没有发现并发问题,试过1000次也没什么问题

3.

可以使用vfork来做到等待子进程结束,具体可见系统手册:
在这里插入图片描述

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/wait.h>int main() {int rc = vfork();if (rc == -1) {fprintf(stderr, "fork failed\n");} else if (rc == 0) {printf("hello\n");} else {printf("goodbye\n");}return 0;
}

另一种实现方式:

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/wait.h>
#include <stdlib.h>int flag = 0;int main() {int rc = vfork();if (rc == -1) {fprintf(stderr, "fork failed\n");} else if (rc == 0) {printf("hello\n");flag = 1;exit(1);} else {while(flag == 0);printf("goodbye\n");wait(NULL);}return 0;
}

最终输出如下:
在这里插入图片描述

4.

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/wait.h>
#include <stdlib.h>int main() {int i; for (i = 1; i <= 6; ++i) {int rc = fork();if (rc == -1) {fprintf(stderr, "fork failed\n");exit(1);} else if (rc == 0) {char* path = "/bin/ls";char* pro = "ls";char* target = ".";char* ev[] = {pro, target, NULL};switch (i){case 1:execl(path, pro, target, NULL);break;case 2:execle(path, pro, target, NULL);break;case 3:execlp(pro, pro, target, NULL);break;case 4:execv(path, ev);break;case 5:execvp(pro, ev);break;case 6:execvpe(pro, ev);break;default:break;}} else {wait(NULL);}}return 0;
}

结果如下:
在这里插入图片描述

5.

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/wait.h>
#include <stdlib.h>int main() {int rc = vfork();if (rc == -1) {fprintf(stderr, "fork failed\n");} else if (rc == 0) {wait(NULL);printf("child pid is %d\n", getpid());exit(1);} else {int result = wait(NULL);printf("the return value is %d\n", result);exit(1);}return 0;
}

在这里插入图片描述
从上图中可见,wait返回的是子进程的进程号,而子进程中使用wait并不会发生什么,它会等待子进程自己的子进程结束。

6.

在这里插入图片描述
同样是返回pid,但是waitpid传入的参数不同,需要传入子进程的id、状态参数以及额外的选项。

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/wait.h>
#include <stdlib.h>int main() {int rc = vfork();if (rc == -1) {fprintf(stderr, "fork failed\n");} else if (rc == 0) {printf("child pid is %d\n", getpid());exit(1);} else {int result = waitpid(rc, NULL, 0);printf("the return value is %d\n", result);exit(1);}return 0;
}

结果如下图所示:
在这里插入图片描述

7.

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/wait.h>
#include <errno.h>
#include <string.h>int main() {int rc = fork();if (rc == -1) {fprintf(stderr, "fork failed\n");} else if (rc == 0) {close(STDOUT_FILENO);int res = printf("output something\n");fprintf(stderr, "%d\n", res);res = fflush(stdout);fprintf(stderr, "%d %s\n", res, strerror(errno));} else {wait(NULL);}return 0;
}

在这里插入图片描述
会把数据先写在缓存块内,具体可参考:在关闭stdout之后调用printf会发生什么?

8.

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/wait.h>int main() {int fds[2];pipe(fds);int rc = fork();if (rc == -1) {fprintf(stderr, "fork failed\n");} else if (rc == 0) {close(STDOUT_FILENO);close(fds[1]);dup(fds[0]);close(fds[0]);}rc = fork();if (rc == -1) {fprintf(stderr, "fork failed\n");} else if (rc == 0) {close(STDIN_FILENO);close(fds[1]);dup(fds[1]);close(fds[1]);printf("hello\n");}close(fds[1]);close(fds[0]);wait(NULL);return 0;
}

结果如下图所示:
在这里插入图片描述

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

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

相关文章

【EI会议征稿通知】第五届机电一体化技术与智能制造国际学术会议(ICMTIM 2024)

第五届机电一体化技术与智能制造国际学术会议&#xff08;ICMTIM 2024&#xff09; 2024 5th International Conference on Mechatronics Technology and Intelligent Manufacturing 第五届机电一体化技术与智能制造国际学术会议&#xff08;ICMTIM 2024&#xff09;将于2024…

解析 ODPS SQL 任务优化方法原理

一文解析 ODPS SQL 任务优化方法原理 本文重点尝试从ODPS SQL的逻辑执行计划和Logview中的执行计划出发,分析日常数据研发过程中各种优化方法背后的原理,覆盖了部分调优方法的分析,从知道怎么优化,到为什么这样优化,以及还能怎样优化。 一、背景 使用ODPS SQL进行离线数据…

深入云原生—基于KubeWharf深度剖析-以公司实际应用场景为例深度解读

各位好&#xff0c;这里是难忘&#xff0c;本人对云原生也是研究了2年多了&#xff0c;算是略有所得&#xff0c;本次就来深入云原生—基于KubeWharf深度剖析场景与解读。我们需要先了解一下 KubeWharf&#xff0c;可能很多人都感觉到有点陌生吧&#xff0c;下面我们来一起学习…

Linux_Centos7安装snmp服务

Linux_Centos7安装snmp服务 1.背景2.目的3.环境4.操作4.1 手动安装snmp协议4.2 批量安装snmp协议 1.背景 收到云平台异常告警&#xff0c;提示ECS服务器在在一分钟内客户端存在多次ssh远程登陆&#xff0c;被判断为ssh远程破解&#xff0c;通过排查得出为运维系统配置过程中错…

Linux安装MongoDB教程

下载MongoDB安装包 1、官网地址; 下载链接 选择版本 下载好了之后上传到服务器开始安装。 解压 解压 mongodb-linux-x86_64-rhel70-4.2.23.tgz 文件&#xff1a; 解压文件必须进入到压缩包所在的目录&#xff1a; cd /usr/local tar -zxvf mongodb-linux-x86_64-rhel70-4…

操作系统课程设计:常用页面置换算法(OPT、FIFO、LRU)的实现及缺页率的计算(C语言)

名人说&#xff1a;莫听穿林打叶声&#xff0c;何妨吟啸且徐行。—— 苏轼《定风波莫听穿林打叶声》 Code_流苏(CSDN)&#xff08;一个喜欢古诗词和编程的Coder&#xff09; 目录 一、效果图二、代码&#xff08;带注释&#xff09;三、说明 一、效果图 二、代码&#xff08;带…

降低运营成本:采用安全托管服务(Managed Security Service,MSS)

文章目录 安全托管服务(MSS)?安全托管服务的内容安全风险评估安全监控预警安全应急响应安全问题咨询 企业为什么需要安全托管服务&#xff1f;与MSS合作的好处是什么&#xff1f;MSP和MSSP有何区别&#xff1f;MSSP如何向客户呈现服务内容企业可以托管哪些网络资产威胁管理托管…

大话 JavaScript(Speaking JavaScript):第二十一章到第二十五章

第二十一章&#xff1a;数学 原文&#xff1a;21. Math 译者&#xff1a;飞龙 协议&#xff1a;CC BY-NC-SA 4.0 Math对象用作多个数学函数的命名空间。本章提供了一个概述。 数学属性 Math的属性如下&#xff1a; Math.E 欧拉常数&#xff08;e&#xff09; Math.LN2 2 …

Clickhouse实时指标加工

Starwift实时指标加工方案 方案介绍 ​ Starwift(ClickHouse)是京东云上的一款云原生数据仓库,为用户带来极速分析体验,能够支撑实时数据分析和海量数据离线分析。便捷的弹性扩缩容能力,极致分析性能和丰富的企业级特性,助力客户数字化转型。实时指标加工是从离线指标加…

常见类型的yaml文件如何编写?--kind: Job|CronJob

本次介绍两个关联度很高的类型&#xff0c;Job和CronJob。 Job基本说明 在 Kubernetes 中&#xff0c;Job 是一种用于运行一次性任务的资源对象。它用于确保在集群内部执行某个任务&#xff0c;即使任务运行失败或其中一个 Pod 发生故障时&#xff0c;也会进行重试。Job 可以…

【设计模式-6】建造者模式的实现与框架中的应用

建造者模式又被成为生成器模式&#xff0c;是一种使用频率比较低&#xff0c;相对复杂的创建型模式&#xff0c;在很多源码框架中可以看到建造者的使用场景&#xff0c;稍后我们会在本文末尾展示几个框架的使用案例。  建造者模式所构造的对象通常是比较复杂而且庞大的&#x…

使用requests库测试post请求 操作流程

第一步 谷歌f12或其他抓包工具抓包&#xff0c;这里随机抓一个post请求 url&#xff1a;https://eva2.csdn.net/v3/06981375190026432f77c01bfca33e32/lts/groups/dadde766-b087-42da-8e67-d2499a520ee7/streams/a0119567-bf91-4314-ab75-f683ba6c0c0a/logs 第二步 导包 impo…