计算机系统基础(第十章)

对cs给的第十章的代码的理解,与运行结果
关于代码如何运行,大概可以用如下的方法:
先用gcc -c 命令生成文件(这里用file.c代替)以及csapp.c的.o文件然后用

gcc -o file file.o csapp.o -lpthread

因为csapp里用到了线程有关的东西,所以要加-lpthread

#include "csapp.h"
int main(int argc, char *argv[])
{
    int fd1, fd2, fd3;
    char c1, c2, c3;
    char *fname = argv[1];
    fd1 = Open(fname, O_RDONLY, 0);
    fd2 = Open(fname, O_RDONLY, 0);
    fd3 = Open(fname, O_RDONLY, 0);
    dup2(fd2, fd3);
    Read(fd1, &c1, 1);
    Read(fd2, &c2, 1);
    Read(fd3, &c3, 1);
    printf("c1 = %c, c2 = %c, c3 = %c\n", c1, c2, c3);
    Close(fd1);
    Close(fd2);
    Close(fd3);
    return 0;
}

abcde.txt文件的内容为abcde
运行./file1 abcde.txt的运行结果如下:
在这里插入图片描述
对于代码的解释,大写的Open,Read,Close仅是在csapp里进行了有关错误的处理,重新定义的函数,其他的均与原函数相同,对于类似的题可以通过画出图来处理,画出的图如下:
图一
在这里插入图片描述

图二
在这里插入图片描述

在用了三个open函数打开了同一文件三次,每次都会在文件打开表里创建一个项,且文件描述符表的项指向打开表中的表项,如第一张图,而调用dup2(fd2,fd3)后将fd2的文件打开表的表项赋给了fd3,所以fd2与fd3指向的是同一个文件打开表的表项,第一条read不必多说,在fd2读了一个字符后,光标往后移一位,因为fd3与fd2的文件打开表的表项相同,所以fd3的read会接着读,所以fd2读的是a,而fd3会接着读a后面的b所以输出的结果是c1 = a,a2 = a,c3 = b(之后不再解释类似问题,建议画图)

#include "csapp.h"
int main(int argc, char *argv[])
{
    int fd1;
    int s = getpid() & 0x1;
    printf("pid = %d,s = %d\n",getpid(),s);
    char c1, c2;
    char *fname = argv[1];
    fd1 = Open(fname, O_RDONLY, 0);
    Read(fd1, &c1, 1);
    if (fork()) {
    /* Parent */
       sleep(s);
       Read(fd1, &c2, 1);
       printf("Parent: c1 = %c, c2 = %c\n", c1, c2);
    } else {
    /* Child */
       sleep(1-s);
       Read(fd1, &c2, 1);
       printf("Child: c1 = %c, c2 = %c\n", c1, c2);
    }
    return 0;
}

我再源代码的基础上作了一些修改添加了

printf(“pid = %d,s = %d\n”,getpid(),s);

这一行,且运行如下./file2 abcde.txt,可以让结果更加的明显,运行的结果如下:
在这里插入图片描述
这里的s为进程的pid与上0x1也就是将进程的pid号最低位(二进制)赋给s,也就是说该进程(fork前)的pid号为奇数则父进程等待1s,偶数则是子进程等待1s,有关的图如下:
图一
在这里插入图片描述
图二
在这里插入图片描述

原本打开文件如图一,因此读出的字符为a,光标往后移一位,之后fork创建子进程,子进程得到了父进程所有的资源,包括打开的文件表,而后因为原进程pid为奇数,所以s为1,1-s为0,所以父进程会等待1s再执行,所以子进程接着往后读得到c2 = b,父进程等待完之后往后读c2 = c,所以有了如图的结果,有趣的是多次执行该程序并不会改变父进程子进程的执行顺序,这是因为创建了一个子进程,所以每次都是执行的两个进程,并不会改变之后执行进程的pid号,这里我们运行题1的程序再运行题2的程序,来改变奇偶性,结果如图:
在这里插入图片描述
这样就变成了父进程先运行,子进程等待1s,对于shell的提示符的解释是:提示符的输出取决于最初的父进程,也就是原进程,一旦父进程结束shell提示符就会输出,而之后运行完的子进程只能再提示符之后输出(这里为个人理解,欢迎指出错误的地方),所以子进程的结果输出在了下一个提示符之后。

#include "csapp.h"
int main(int argc, char *argv[])
{
    int fd1, fd2, fd3;
    char *fname = argv[1];
    fd1 = Open(fname, O_CREAT|O_TRUNC|O_RDWR, S_IRUSR|S_IWUSR);
    Write(fd1, "pqrs", 4); 
    fd3 = Open(fname, O_APPEND|O_WRONLY, 0);
    Write(fd3, "jklmn", 5);
    fd2 = dup(fd1);  /* Allocates new descriptor */
    Write(fd2, "wxyz", 4);
    Write(fd3, "ef", 2);
    Close(fd1);
    Close(fd2);
    Close(fd3);
    return 0;
}

这一题比较麻烦,还是把图画出来:
在这里插入图片描述

开始时这里fd1用open打开文件,带的属性的意思为如果文件不存在则创建文件并打开,存在则打开并且截断它(清空),以可读可写的方式打开,之后在空文件中写入pqrs,此时fd1的光标再s之后,而fd3是在fd1写完之后再打开的,所以打开时里面已经有pqrs存在了,而fd2的打开属性设置是O_APPEND,指的是每次写都在最后,所以fd3写了之后文件的内容为pqrsjklmn,此时fd3的光标在n之后,而之后使用dup函数将fd1的文件打开表项给fd2,所以fd2会接着fd1的光标写入wxyz,也就是在s后面写入第5~8个字符wxyz,也就是原来的jklm被覆盖了,此时文件的内容为pqrswxyzn,之后fd3接着在n后写入ef,到此时文件的内容为pqrswxyznef,所以最后输出的值为pqrswxyznef
程序运行的结果如下:
在这里插入图片描述
在这里插入图片描述

这一题说起来有点悲伤,在第一次做的时候做错了
暂时写到这,欢迎大家指正错误。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
【优质项目推荐】 1、项目代码均经过严格本地测试,运行OK,确保功能稳定后才上传平台。可放心下载并立即投入使用,若遇到任何使用问题,随时欢迎私信反馈与沟通,博主会第一时间回复。 2、项目适用于计算机相关专业(如计科、信息安全、数据科学、人工智能、通信、物联网、自动化、电子信息等)的在校学生、专业教师,或企业员工,小白入门等都适用。 3、该项目不仅具有很高的学习借鉴价值,对于初学者来说,也是入门进阶的绝佳选择;当然也可以直接用于 毕设、课设、期末大作业或项目初期立项演示等。 3、开放创新:如果您有一定基础,且热爱探索钻研,可以在此代码基础上二次开发,进行修改、扩展,创造出属于自己的独特应用。 欢迎下载使用优质资源!欢迎借鉴使用,并欢迎学习交流,共同探索编程的无穷魅力! 基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip 基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip 基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip
提供的源码资源涵盖了安卓应用、小程序、Python应用和Java应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码中配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程中,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码中的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值