【MIT-OS6.S081笔记1】Chapter1阅读摘要:Operating system interfaces

记录阅读《xv6: a simple, Unix-like teaching operating system》的一些摘要,这是第一章的内容:Operating system interfaces。

  1. fork函数作用:fork创建一个新进程,称为子进程,其内存内容与调用进程(称为父进程)完全相同。fork在父进程和子进程中都会返回。在父进程中,fork返回子进程的 PID;在子进程中,fork返回零。
  2. exit作用:exit系统调用使调用进程停止执行并释放诸如内存和打开的文件等资源。exit接收一个整数状态参数,按照惯例,0 表示成功,1 表示失败。
  3. wait作用:wait系统调用返回当前进程已退出(或被终止)的子进程的 PID,并将子进程的退出状态复制到传递给wait的地址;如果调用者的子进程都没有退出,wait会等待其中一个退出。如果调用者没有子进程,wait立即返回 -1。如果父进程不关心子进程的退出状态,它可以向wait传递一个地址为 0 的参数。
  4. exec作用:exec系统调用用从文件系统中存储的文件加载的新内存映像替换调用进程的内存。该文件必须具有特定的格式,该格式指定文件的哪个部分保存指令、哪个部分是数据、从哪个指令开始等等。xv6 使用 ELF 格式,当exec成功时,它不会返回到调用程序;相反,从文件加载的指令从 ELF 头中声明的入口点开始执行。exec接受两个参数:包含可执行文件的文件名和一个字符串参数数组。
  5. shell的原理:主循环使用getcmd从用户读取一行输入。然后它调用fork,这会创建一个 shell 进程的副本。父进程调用wait,而子进程运行命令。例如,如果用户向 shell 输入了 “echo hello”,那么runcmd将以 “echo hello” 作为参数被调用。runcmd(在user/sh.c:58)运行实际的命令。对于 “echo hello”,它将调用exec(在user/sh.c:78)。如果exec成功,那么子进程将执行来自echo的指令而不是runcmd。在某个时刻,echo将调用exit,这将使父进程从main函数中的wait返回(在user/sh.c:145)。
  6. 你可能会想为什么fork和exec不在一个单独的调用中;我们稍后会看到,在实现输入 / 输出重定向时,shell 利用了这种分离。为了避免创建一个重复的进程然后立即用exec替换它的浪费,操作系统内核通过使用诸如写时复制(见第 4.6 节)等虚拟内存技术来优化这种用例下fork的实现。进一步说明:为什么fork和exec是分开的调用是有帮助的了:在这两个调用之间,shell 有机会重定向子进程的 I/O,而不会干扰主 shell 的 I/O 设置。
  7. 隐式分配内存:fork为子进程分配复制父进程内存所需的内存,exec分配足够的内存来容纳可执行文件。一个在运行时需要更多内存(可能用于malloc)的进程可以调用sbrk(n)来将其数据内存增加n个字节;sbrk返回新内存的位置。
  8. 惯例:进程从文件描述符 0(标准输入)读取数据,将输出写入文件描述符 1(标准输出),并将错误消息写入文件描述符 2(标准错误)。shell 利用这个惯例来实现 I/O 重定向和管道。shell 确保它始终有三个打开的文件描述符(在user/sh.c:151),默认情况下这些是控制台的文件描述符。
  9. read作用:文件描述符fd中最多读取n个字节,将它们复制到buf中,并返回读取的字节数。每个指向文件的文件描述符都有一个与之相关联的偏移量。read从当前文件偏移量处读取数据,然后将该偏移量增加读取的字节数:后续的读取将返回第一次读取返回的字节之后的字节。当没有更多字节可读时,read返回 0 以表示文件结束。
  10. write作用:将buf中的n个字节写入文件描述符fd并返回写入的字节数。只有在发生错误时才会写入少于n个字节。与read类似,write在当前文件偏移量处写入数据,然后将该偏移量增加写入的字节数:每次写入都从上一次写入的位置继续。
  11. cat的说明:cat不知道它是从文件、控制台还是管道中读取数据。类似地,cat也不知道它是将内容输出到控制台、文件还是其他地方。文件描述符的使用以及文件描述符 0 是输入、文件描述符 1 是输出的惯例使得cat的实现很简单。
  12. close作用:close系统调用释放一个文件描述符,使其可以在未来的open、pipe或dup系统调用中被重用(见下文)。新分配的文件描述符始终是当前进程中未使用的编号最小的描述符。
  13. fork的进一步说明:文件描述符与fork相互作用,使得 I/O 重定向易于实现。fork会连同内存一起复制父进程的文件描述符表,因此子进程开始时与父进程具有完全相同的打开文件。系统调用exec会替换调用进程的内存,但保留其文件表。这种行为允许 shell 通过fork实现 I/O 重定向,在子进程中重新打开选定的文件描述符,然后调用exec来运行新程序。
  14. open作用:open的第二个参数由一组以位表示的标志组成,用于控制open的行为。可能的值在文件控制(fcntl)头文件(在kernel/fcntl.h:1 - 5)中定义:O_RDONLY(只读)、O_WRONLY(只写)、O_RDWR(读写)、O_CREATE(如果文件不存在则创建文件)和O_TRUNC(将文件截断为零长度)。
  15. dup作用:dup系统调用复制一个现有的文件描述符,返回一个新的文件描述符,该新描述符指向相同的底层 I/O 对象。两个文件描述符共享一个偏移量,就像由fork复制的文件描述符一样。
  16. 命令行ls existing-file non-existing-file > tmp1 2>&1解释:

这是执行 “ls” 命令,列出 “existing-file”(现有文件)和 “non-existing-file”(不存在的文件)的信息。
> tmp1
这是输出重定向操作。它将 “ls” 命令的标准输出(通常是文件和目录的列表信息)重定向到文件 “tmp1” 中。这意味着 “ls” 命令产生的正常输出内容将被写入到 “tmp1” 文件中,而不是显示在终端上。
2>&1
这里 “2” 代表标准错误输出(stderr),“1” 代表标准输出(stdout)。“2>&1” 的意思是将标准错误输出重定向到与标准输出相同的地方。
在这个例子中,由于前面已经将标准输出重定向到了 “tmp1” 文件,所以这个操作会使得 “ls” 命令在遇到 “non-existing-file”(不存在的文件)时产生的错误信息(标准错误输出)也被写入到 “tmp1” 文件中。 总的来说,这个命令的作用是执行 “ls” 命令列出两个文件的信息,并将正常输出和错误输出都写入到文件 “tmp1” 中。尽管xv6 shell 不支持错误文件描述符的 I/O 重定向,但现在你知道如何实现它了。

  1. 管道描述: 一个由内核管理的小缓冲区,以一对文件描述符的形式呈现给进程,一个用于读取,一个用于写入。向管道的一端写入数据,就可以从管道的另一端读取这些数据。管道为进程间通信提供了一种方式。
    管道的优点:
  • 首先,管道会自动清理自身。使用文件重定向时,shell 必须小心地在完成后删除 “/tmp/xyz” 这样的临时文件。如果不进行清理,临时文件可能会占用磁盘空间并逐渐积累,导致混乱。
  • 其次,管道可以传递任意长度的数据流。而文件重定向需要磁盘上有足够的可用空间来存储所有数据。如果数据量非常大,可能会超出磁盘空间的限制,而管道则不受此限制,只要内存能够处理,就可以持续传递数据。
  • 第三,管道允许管道的各个阶段并行执行。在使用管道时,各个阶段可以同时进行数据处理,提高效率。而使用文件的方法要求第一个程序完成后,第二个程序才能开始。这会导致时间上的延迟,特别是当处理大量数据或复杂任务时。
  • 第四,如果正在实现进程间通信,管道的阻塞式读写比文件的非阻塞语义更高效。在管道中,当没有数据可读时,读操作会自动阻塞等待数据到来;当没有空间可写时,写操作会阻塞等待空间释放。这种机制使得进程可以更高效地同步和协调,而不需要不断地轮询文件状态。相比之下,使用文件进行进程间通信可能需要更复杂的同步机制,并且非阻塞的文件操作可能会导致频繁的检查和浪费资源。
  1. 程序解释:
int p[2];
char *argv[2];
argv[0] = "wc";
argv[1] = 0;
pipe(p);
if(fork() == 0) {
close(0);
dup(p[0]);
close(p[0]);
close(p[1]);
exec("/bin/wc", argv);
} else {
close(p[0]);
write(p[1], "hello world\n", 12);
close(p[1]);
}
  • 子进程dup(p[0])复制管道的读端文件描述符到最小可用的文件描述符,通常是 0,这样就将子进程的标准输入重定向到管道的读端。因为要重定向所以close(0),子进程调用close和dup以使文件描述符 0 指向管道的读端,关闭p中的文件描述符,并调用exec来运行wc。当wc从其标准输入读取时,它从管道中读取。
  • 父进程:向管道的写端写入字符串"hello world\n",长度为 12 个字节。这样写入的数据可以在子进程中通过管道的读端读取。父进程关闭管道的读端,向管道写入数据,然后关闭写端。
  • 进一步解释:如果子进程在执行wc命令时,没有关闭管道的写端,那么当wc从管道读取数据时,由于不知道是否还会有新数据写入管道,所以read操作会一直阻塞等待。只有当所有指向管道写端的文件描述符都被关闭时,read才会返回 0,表示到达文件末尾,wc才能正常结束执行。因此,为了确保wc能正确读取管道中的数据并在适当的时候结束,子进程在执行wc之前要关闭管道的写端。
  • 如果没有数据可用,对管道的读操作会等待数据被写入或者所有指向写端的文件描述符都被关闭;在后一种情况下,read将返回 0,就好像到达了数据文件的末尾。read会阻塞直到不可能有新数据到达这一事实,是上述代码中在执行wc之前子进程要关闭管道写端的一个重要原因:如果wc的一个文件描述符指向管道的写端,那么wc将永远不会看到文件结束标志。
  • 我的理解:父子进程都有文件描述符,为了使所有写端的文件描述符都被关闭让wc的read成功退出,那么我们需要保证读wc之前要关闭写端,否则wc的一个文件描述符指向管道的写端导致wc永远看不到文件结束标志。
  1. 命令行grep fork sh.c | wc -l解释:在文件 “sh.c” 中搜索包含 “fork” 的行,然后统计这些匹配行的数量
  2. shell 可能会创建一个进程树。这个树的叶子是命令,内部节点是等待左右子进程完成的进程。fork是相辅相成的,左端fork右端也需要fork:如对于p->left不进行fork操作,而是在内部进程中运行runcmd(p->left)。那么,例如,“echo hi | wc” 将不会产生输出,因为当 “echo hi” 在runcmd中退出时,内部进程退出并且永远不会调用fork来运行管道的右端。这种不正确的行为可以通过在内部进程的runcmd中不调用exit来修复,但这个修复会使代码变得复杂:现在runcmd需要知道它是否是一个内部进程。当对runcmd(p->right)也不进行fork操作时,也会出现复杂情况。例如,仅进行那个修改,“sleep 10 | echo hi” 将立即打印 “hi” 而不是在 10 秒后,因为 “echo” 立即运行并退出,而不是等待 “sleep” 完成。由于sh.c的目标是尽可能简单,所以它不会尝试避免创建内部进程。
  3. mkdir作用:创建新的目录,使用O_CREATE标志的open用于创建新的数据文件
  4. mknod作用:创建新的设备文件,该文件指向一个设备。与设备文件相关联的是主设备号和次设备号(mknod的两个参数),它们唯一地标识一个内核设备。当一个进程稍后打开一个设备文件时,内核将read和write系统调用转移到内核设备实现,而不是将它们传递给文件系统。
  5. 一个文件的名称与文件本身是不同的;同一个底层文件,称为索引节点(inode),可以有多个名称,称为链接。每个链接由目录中的一个条目组成;该条目包含一个文件名和对一个 inode 的引用。一个 inode 保存关于文件的元数据,包括它的类型(文件、目录或设备)、它的长度、文件内容在磁盘上的位置以及指向一个文件的链接数量。
#define T_DIR 1 // Directory
#define T_FILE 2 // File
#define T_DEVICE 3 // Device
struct stat {
int dev; // File system’s disk device
uint ino; // Inode number
short type; // Type of file
short nlink; // Number of links to file
uint64 size; // Size of file in bytes
};
  1. link作用:创建另一个文件系统名称,该名称与现有文件指向同一个索引节点(inode)。以下代码片段创建了一个新文件,它有两个名称 “a” 和 “b”。
open("a", O_CREATE|O_WRONLY);
link("a", "b");
  1. 从 “a” 读取或写入与从 “b” 读取或写入是相同的。每个索引节点(inode)由一个唯一的 inode 编号标识。在上述代码序列之后,可以通过检查fstat的结果来确定 “a” 和 “b” 指向相同的底层内容:两者将返回相同的 inode 编号(ino),并且链接计数(nlink)将被设置为 2。
  2. unlink作用:有点类似于引用计数,此时,虽然从文件系统中删除了名称 “a”,但文件的内容仍然存在,因为 “b” 仍然引用着该文件的 inode。只有当再次执行unlink(“b”)且没有其他文件描述符引用该文件时,文件的 inode 和占用的磁盘空间才会被释放。这体现了文件系统中链接计数的作用,确保在没有任何引用时才真正释放文件资源。
  3. 下面的程序是一种惯用法,用于创建一个没有名称的临时 inode。当进程关闭文件描述符 “fd” 或退出时,这个临时 inode 将会被清理掉。这样可以方便地创建临时文件,而无需在后续手动清理文件名,避免了文件名的混乱和资源泄漏的风险。
fd = open("/tmp/xyz", O_CREATE|O_RDWR);
unlink("/tmp/xyz");
  1. cd描述:cd不派生子进程:一个例外是 cd,它内置于 shell 中(在 user/sh.c:160)。cd 必须更改 shell 本身的当前工作目录。如果 cd 作为常规命令运行,那么 shell 将派生一个子进程,子进程将运行 cd,并且 cd 将更改子进程的工作目录。而父进程(即 shell)的工作目录将不会改变。
  2. 任何操作系统都必须将进程复用到底层硬件上,将进程彼此隔离,并提供受控的进程间通信机制

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

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

iMeta | 复杂热图(ComplexHeatmap)可视化文章最新版,画热图就引它

复杂热图可视化 https://doi.org/10.1002/imt2.43 PROTOCOL ●2022年8月,德国癌症研究中心顾祖光在iMeta在线发表了题为“Complex heatmap visualization”的方法类文章。 ● 该研究系统性地介绍了 ComplexHeatmap R包在复杂热图可视化方面的特性和功能。 ● 第…

HTTP的了解

从输入 URL 到页面展示到底发生了什么?(非常重要) 类似的问题:打开一个网页,整个过程会使用哪些协议? 先来看一张图(来源于《图解 HTTP》): 上图有一个错误需要注意&…

博弈论(所有情况最优解)——课堂笔记

博弈论(所有情况最优解)——课堂笔记|【博弈论】分割数游戏-CSDN博客https://blog.csdn.net/back_room/article/details/143464453?spm=1001.2014.3001.5501【博弈论】拍卖土地-CSDN博客

网络编程——TCP通信练习

目录 一、多发多收 二、接收和反馈 三、上传文件 四、解决上传文件名重复问题 五、上传文件多线程版 六、上传文件线程池版 七、B/S(接收浏览器的消息并打印) 一、多发多收 客户端:多次发送数据 服务器:接收多次数据,并打印 public cl…

Selenium自动化测试 —— 模拟鼠标键盘的操作事件

软件测试资料领取:[内部资源] 想拿年薪40W的软件测试人员,这份资料必须领取~ 软件测试面试刷题工具:软件测试面试刷题【800道面试题答案免费刷】 鼠标操作事件 在实际的web产品测试中,对于鼠标的操作,不单单只有clic…

线性回归模型

线性回归模型 代价函数 梯度下降 学习率 梯度下降的收敛与调优 梯度下降的收敛性依赖于以下因素: 学习率的选择:合适的学习率能够确保稳定收敛,过大或过小的学习率可能会导致收敛不稳定或效率低下。数据的特征:数据的规模和特征…

书生大模型基础岛第一关书生大模型全链路开源体系

本文档相当于是对书生*浦语的了解文档 官网: https://internlm.intern-ai.org.cn/ github: https://github.com/internLM/ 开源之路: 2023.7.6 InterLM-7B2023.9.20 InterLM-20B2024.1.17 InternLM22024.7.4 InternLM2.5 性能天梯: InternL…

01OpenGL基本学习

文章目录 第一节1、概念立即模式vs核心模式 2、问题 第二节1、三维坐标系![三维坐标系](https://i-blog.csdnimg.cn/direct/0703ba6b68914b08b1d14b936ccd862d.png)2、什么是模型?3、什么是颜色?4、材质 第三节渲染管线第四节GLAD配置流程1、为什么需要G…

测试-请求特定资源使用Postman工具(3)

目录 前言 实操 开发者工具 前言 介绍过,就不再介绍了,只需要知道它是一个网络请求的工具就行了 实操 开发者工具 这里我们还需要借助开发者工具来帮助我们进行资源的请求,这里用 百度一下 进行测试 如下是 百度一下 的首页 右键打开…

Foliate:沉浸式阅读!!!

项目简介 Foliate 是一款开源的电子书阅读器,专为现代操作系统设计,提供了优雅且实用的阅读体验。它支持多种电子书格式,包括 EPUB、Mobipocket、Kindle、FB2、CBZ 和 PDF,让用户能够以分页或滚动模式阅读。Foliate 允许用户自定义…

打包18款AI营销神器,批量运营项目收藏必备!

淘金的不如卖铲子的,AI工具的应用越来越普及,这也让很多原本淘金的人都来卖铲子。如果自己能有很好的铲子,自己也会淘金,就可以既能卖铲子赚钱,也能掏金赚钱。 还有两天就是双十一了,各种AI工具&#xff0…

【MyBatis源码】SQL 语句构建器AbstractSQL

文章目录 介绍org.apache.ibatis.jdbc.SQLSQL类使用示例SelectProvider搭配动态SQLAbstractSQL类源码分析 介绍 当我们需要使用Statement对象执行SQL时,SQL语句会嵌入Java代码中。SQL语句比较复杂时,我们可能会在代码中对SQL语句进行拼接,查…

Vue2进阶

1.el安装 官网地址 Element - The worlds most popular Vue UI frameworkElement,一套为开发者、设计师和产品经理准备的基于 Vue 2.0 的桌面端组件库https://element.eleme.cn/#/zh-CN 安装 npm install element-ui -S 引入组件(在 main.js&#xf…

案例:三次锁定(下)

第二步: 在 Form1.cs 中完成以下代码 using Dome16_三次锁定.service; using Dome16_三次锁定.service.serviceimpl; using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using Sys…

前端学习笔记—Vue3特性

一、 Vue3与Vite构建工具简介 image.png image.png image.png image.png Vite构建工具(其他的打包工具有webpack,grunt,gulp) image.png image.png 构建 二、创建Vue3项目 vite在TypeScript结合使用上,直接开箱即用&am…

iOS 去掉URL里面的百分号符号

遇到这个一段字符串 “publicId2030095197043302&publicBizTypeCONTENT_USER&chInfoch_life__chsub_Ndiscovery.featured&logoUrlhttps%3A%2F%2Fmdn.alipayobjects.com%2Fopen_content%2Fafts%2Fimg%2FA*_SUKQodfigcAAAAAAAAAAAAAfVx1AQ%2Foriginal&publicName…

node.js安装配置(Windows)

1、下载 CNPM Binaries Mirror 2、安装 3、验证 win R 进入cmd 4、配置环境变量 4.1、创建两个文件夹 4.2、安装目录进入cmd(配置全局属性) 配置两个命令: npm config set prefix "D:\liyunqing\nodejs\node_global"npm config set cache "D:\l…

jdbc中预防SQL攻击

目录 展示SQL攻击 举一个出现sql 攻击的例子 SQL攻击的原因 分析原因 阻止SQL攻击 PreparedStatement的含义 使用PreparedStatement的原因 步骤如下 注意 总结 展示SQL攻击 举一个出现sql 攻击的例子 假设我们在做登录业务时,思路是这样的: 首…

30.1 时序数据库TSDB的典型特点

本节重点介绍 : db-ranking网站对db进行排名时序数据特点时序数据库特点时序数据库遇到的挑战开源时间序列数据库 db-ranking 一个神奇的网站 https://db-engines.com/en/ranking 时序数据ranking https://db-engines.com/en/ranking/timeseriesdbms 排名方法 https://db-en…

14:00面试,14:06就出来了,问的问题过于变态了。。。

我从一家小公司转投到另一家公司,期待着新的工作环境和机会。然而,新公司的加班文化让我有些始料未及。虽然薪资相对较高,但长时间的工作和缺乏休息使我身心俱疲。 就在我逐渐适应这种高强度的工作节奏时,公司突然宣布了一则令人…