MIT6.S081 - Lecture1: Introduction and Examples

这篇具有很好参考价值的文章主要介绍了MIT6.S081 - Lecture1: Introduction and Examples。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

课程简介

课程目标

  1. 理解操作系统的设计和实现
  2. 通过 XV6 操作系统动手实验,可以扩展或改进操作系统

操作系统的目标

  1. Abstraction:对硬件进行抽象
  2. Multiplex:在多个应用程序之间共用硬件资源
  3. Isolation:隔离性,程序出现故障时,不同程序之间不能相互干扰
  4. Sharing:实现共享,如数据交互或协同完成任务
  5. Security:想分享的时候可以分享,不想分享的时候可以不分享,可以称为 Access Control System
  6. Performance:操作系统至少需要不阻止应用程序获得高性能,甚至需要帮助应用程序获取高性能
  7. Range of oses:对于大部分操作系统,需要支持大量不同类型的应用程序

操作系统结构

MIT6.S081 - Lecture1: Introduction and Examples

系统调用函数

read/write 系统调用

  • readwrite 函数在执行时,不会关心读写的数据格式,操作系统中(内核)copy 程序会按照 8bit 的字节流处理数据
  • readwrite 函数中第一个参数代表文件位置,shell 会确保默认情况下,当一个程序启动时,文件描述符 0 连接到 console 的输入,文件描述符 1 连接到了 console 的输出。

open 系统调用

  • 字节流就是一段连续的数据按照字节的长度读取
  • open("output.txt", O_WRONLY | O_CREATE); 第二个参数用来告诉 open 系统调用在内核中的实现:我们将要创建写入一个文件
  • 文件描述符本质上对应了内核中的一个表单数据。内核维护了每个运行进程的状态,内核会为每一个运行进程保存一个表单,表单的 key 是文件描述符。这个表单让内核知道,每个文件描述符对应的实际内容是什么。这里比较关键的点是,每个进程都有自己独立的文件描述符空间,所以如果运行了两个不同的程序,对应两个不同的进程,如果它们都打开一个文件,它们或许可以得到相同数字的文件描述符,但是因为内核为每个进程都维护了一个独立的文件描述符空间,这里相同数字的文件描述符可能会对应到不同的文件

fork 系统调用

  • fork 可以创建新的进程,该进程(子进程)与原进程(父进程)的指令、数据、堆栈、文件描述符表单完全相同

  • fork 有两个返回值,但是有独立的地址空间(都认为内存从 0 开始增长)

    • 在父进程中,返回子进程的 PID
    • 在子进程中,返回 0
    • 如果创建失败,返回-1

wait 系统调用

  • wait 表示等待一个子进程退出

    • 如果调用者没有子进程,则 wait 立即返回-1
    • 如果父进程不关注子进程的退出时状态,可以传一个 0 地址(或者 NULL 指针)给 wait
    pid = wait((int *)0);   // 只要一个子进程退出,wait 就结束,返回该退出的子进程的 pid 号
    
    • 如果父进程关注子进程的退出时状态,可以使用如下方式,status将保存子进程结束时的状态(子进程退出时exit里的参数会被保存到status中)
    int status;
    wait(&status);
    

exit 系统调用

  • exit 系统调用退出程序,并释放资源。exit 需要一个整数状态参数,0 表示成功,1 表示失败

exec 系统调用

  • exec 系统调用使用新内存映像来替换内存的进程
    • exec 会保留当前的文件描述符
    • 通常 exec 不会返回,只有出错时才会返回
_char _*argv[3]; 
argv[0] = "echo"; 
argv[1] = "hello"; 
argv[2] = 0;      // 标记了数组的结尾,也可以用NULL指针
exec("/bin/echo", argv);   // 相当于echo hello
printf("exec error\n");    // exec出错时返回,否则不会运行到这里了
  • 一般来说 fork 下的子进程中调用 exec 函数来替换子进程,但这样会造成资源浪费,因此内核通过使用虚拟内存技术来进行优化

pipe 系统调用

管道的概念

  1. 以文件描述符对的形式提供给进程,一个表示读端,一个表示写端
  2. 本质是一个伪文件,实质为内核缓冲区
  3. 管道实际为内核使用环形队列机制,借助内核缓冲区(4K)实现

管道的局限性

  1. 必须作用在有血缘关系的进程之间
  2. 数据不能进程自己写,自己读(需要两个进程,一个读,一个写)
  3. 采用半双工通信,数据只能单方向流动
  4. 数据不能反复读取

管道函数

int pipe(int fd[2]) :创建并打开管道

  • 参数:fd[0] 读端fd[1] 写端
  • 返回值:0 成功;-1 失败

管道程序举例

int p[2]; 
char *argv[2]; 
argv[0] = "wc"; 
argv[1] = 0; 
pipe(p);            // 创建并打开管道
if (fork() == 0)   // 子进程
{ 
    close(0);     // 释放文件描述符0(标准输入)
    dup(p[0]);    // 使得文件描述符0引用了管道读端p[0]
    close(p[0]);  // 关闭管道读端
    close(p[1]);  // 关闭管道写端 
    exec("/bin/wc", argv);  // wc相当于从管道读数据(这里其实不太理解,管道不是关上了吗)
} 
else             // 父进程
{ 
    close(p[0]);   // 读写只能有一个,父进程将读端关闭
    write(p[1], "hello world\n", 12);  // 向管道写入数据
    close(p[1]);  // 写完将管道关闭
}

管道的读写行为

  1. 读管道:
  • 管道中有数据,read 返回实际读到的字节数

  • 管道中无数据:

    • 管道写端全部关闭read 返回 0
    • 管道写端没有全部关闭read 阻塞等待
  1. 写管道:
  • 管道读端全部关闭,进程异常终止(SIGPIPE 信号导致的)

  • 管道读端没有全部关闭

    • 管道已满,write 阻塞
    • 管道未满,write 将数据写入,并返回实际写入的字节数

File system

文件系统

  1. xv6 文件系统包含了数据文件(拥有字节数组)和目录(拥有对数据文件和其他目录的命名引用)
  2. / 开头的如 /a/b 表示根目录 /a 目录中名为 b 的文件或目录(绝对路径),不以 / 开头的是相对于当前目录的路径(相对路径)

chdir 系统调用

通过 chdir 系统调用可以改变进程的当前目录,如下两个 open 打开了同一个文件

chdir("/a");
chdir("b");
open("c", O_RDONLY);
open("/a/b/c", O_RDONLY);

创建文件和目录

mkdir 可以创建一个新的目录open 使用 O_CREATE 可以创建新的数据文件mknod 可以创建一个新的设备文件

mkdir("/dir");
fd = open("/dir/file", O_CREATE | O_WRONLY);
close(fd);

mknod("/console", 1, 1);  // 主设备号,次设备号,唯一标识一个内核设备

当一个进程打开设备文件后,内核会将系统的读写调用转移到内核设备实现上,而不是将它们传递给文件系统

文件链接

  • inode 是操作系统用来储存除了文件名和实际数据的数据结构,它是用来连接实际数据和文件名的;每个 inode 保存着文件的元数据,包括文件的类型(文件 or 目录 or 设备)、长度、内容在磁盘的位置以及文件的链接数量
  • fstat 系统调用从文件描述符引用的 inode 中检索信息
// int fstat(int fd, struct stat*),stat为接收inode信息的结构体,如fstat(fd, &st)
#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
};
  • link 系统调用创建了一个引用同一个 inode 的文件
open("a", O_CREATE | O_WRONLY);
link("a", "b");  // 创建文件b,且a和b指向同一个inode
  • unlink 系统调用会从文件系统中删除一个文件名,只有当文件链接数为且没有文件描述符引用它时,文件 inode 和存放其内容的磁盘空间才会被释放
unlink("a");   // 删除a,此时只有b引用inode

// 创建临时文件的一种惯用方式,它创建一个无名称的inode,在进程关闭fd或退出时删除文件
fd = open("/tmp/x", O_CREATE | O_WRONLY);
unlink("/tmp/x");

Linux 命令

xargs 命令

  • 作用:将标准输入转为命令行参数;xargs 的作用在于,大多数命令(比如 rmmkdirls)与管道一起使用时,都需要 xargs 将标准输入转为命令行参数。
$ echo "hello world" | xargs echo
hello world

上面的代码将管道左侧的标准输入,转为命令行参数 hello world,传给第二个 echo 命令

$ echo "one two three" | xargs mkdir

上面的代码等同于 mkdir one two three。如果不加 xargs 就会报错,提示 mkdir 缺少操作参数

  • 命令格式如下:
$ xargs [-options] [command]

真正执行的命令,紧跟在 xargs 后面,接受 xargs 传来的参数文章来源地址https://www.toymoban.com/news/detail-852652.html

到了这里,关于MIT6.S081 - Lecture1: Introduction and Examples的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • MIT6.828/6.S081 Mac OS下搭建xv6和risc-v

    题外话: 其实我是一名非计算机专业的在校生,因为对软件开发和服务器开发很感兴趣,并且这方面的就业相对我来说资源比较充沛,所以就学习了mit6.828的实验 课程的学习直接跟着官网的schedule走就行,先看Lecture下提供的讲义和手册,然后完成相应的Lab,Lab共计10个,主要

    2024年03月09日
    浏览(36)
  • MIT 6s081 lab1:Xv6 and Unix utilities

    作业网址:https://pdos.csail.mit.edu/6.828/2020/labs/util.html 下载,启动xv6系统 使用system call sleep .函数(在user/user.h中被声明)来完成 使用系统调用在一对管道上的两个进程之间“乒乓”一个字节,每个方向一个。父进程应该向子进程发送一个字节;子进程应打印“<pid>:received

    2024年01月17日
    浏览(37)
  • MIT6.024学习笔记(三)——图论(2)

    科学是使人变得勇敢的最好途径。——布鲁诺 在通信网络中,分为主机和路由器两部分,我们将主机分为输入端和输出端,则构成的图中有三部分:路由器、输入端、输出端,构成了一个有向图。那么,一个N*N规模的通信网络,应该怎么构成才能达到性能最佳呢(假设N总是

    2024年02月09日
    浏览(47)
  • mit6.828 - lab5笔记(上)

    unix的文件系统相关知识 unix将可用的磁盘空间划分为两种主要类型的区域: inode区域 和 数据区域 。 unix为每个文件分配一个inode,其中保存文件的 关键元数据 ,如文件的stat属性和指向文件数据块的指针。 数据区域中的空间会被分成大小相同的数据块(就像内存管理中的分

    2024年02月02日
    浏览(34)
  • MIT 6.S081 Lab Three

    本文为 MIT 6.S081 2020 操作系统 实验三解析。 MIT 6.S081课程前置基础参考: 基于RISC-V搭建操作系统系列 在本实验中,您将探索页表并对其进行修改,以简化将数据从用户空间复制到内核空间的函数。 开始编码之前,请阅读xv6手册的第3章和相关文件: * kernel/memlayout.h* ,它捕获了

    2024年02月09日
    浏览(46)
  • MIT 6.S081学习笔记(第〇章)

    本文涉及 xv6 《第零章 操作系统接口》相关,主要对涉及的进程、I/O、文件描述符、管道、文件等内容产生个人理解,不具有官方权威解释; 文章的目录与书中的目录没有严格的相关性; 文中会有问题 (Question) 字段,这来源于对 xv6 book 的扩展; 文中涉及的代码均能在macOS

    2024年02月09日
    浏览(48)
  • MIT6.5830 Lab1-GoDB实验记录(四)

    标签:Golang 读写缓冲区我是一点思路都没有,所以得单独开篇文章记录。 实验补充 了解buffer、序列化与反序列化 这里的序列化,简单来说类似于把一个很长的字符串拆成一个个字符;反序列化就是把这一个个字符拼回成完整的字符串。此处我们需要根据所给的Tuple,转换为

    2024年02月06日
    浏览(50)
  • MIT6.5830 Lab1-GoDB实验记录(五)

    完成了Exercise 1,还有四个Exercise在等着我,慢慢来吧。 实验准备 了解缓冲池 缓冲池,俗称BP。相关的概念还有数据页和缓存页。页(Pages)的概念和操作系统中“分页”的概念是一样的,指的都是把逻辑地址空间分为若干同等大小的页,并从0开始编号。 而缓冲池(Buffer Po

    2024年02月05日
    浏览(46)
  • 【MIT 6.S081】Lab7: Multithreading

    本Lab比较简单,就是为xv6添加一个用户级的多线程功能,然后熟悉一下Linux下多线程编程。 笔者用时约2h 这一部分的代码不涉及内核代码,所以也比较简单,根据提示修改 user/uthread.c 中的代码即可。仿照内核中进程转换函数 swtch 的实现即可。首先,添加一个 context 上下文结

    2023年04月09日
    浏览(35)
  • (MIT6.045)自动机、可计算性和复杂性-图灵机

    有穷自动机(FA)对有限存储量设备是比较好的模型,下推自动机对无限存储设备是较好的模型(但是其存储只能用后进先出的栈模式来使用。)这两个模型过于局限,不能作为通用模型。 和FA相似,但是图灵机有无限的存储。图灵机可以作实际计算机做的所有事情。但是也有图

    2024年02月08日
    浏览(39)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包