接下来,我将讨论对于应用程序来说,系统调用长成什么样。因为系统调用是操作系统提供的服务的接口,所以系统调用长什么样,应用程序期望从系统调用得到什么返回,系统调用是怎么工作的,这些还是挺重要的。你会在第一个lab中使用我们在这里介绍的系统调用,并且在后续的lab中,扩展并提升这些系统调用的内部实现。

我接下来会展示一些简单的例子,这些例子中会执行系统调用,并且我会在XV6中运行这些例子。XV6是一个简化的类似Unix的操作系统,而Unix是一个老的操作系统,但是同时也是很多现代操作系统的基础,例如Linux,OSX。所以Unix使用的非常广泛。而作为我们教学用的操作系统,XV6就要简单的多。它是受Unix启发创造的,有着相同的文件结构,但是却要比任何真实的Unix操作系统都要简单的多。因为它足够简单,所以你们极有可能在几周内很直观的读完所有的代码,同时也把相应的书也看完,这样你们就能理解XV6内部发生的一切事情了。

XV6运行在一个RISC-V微处理器上,而RISC-V是MIT6.004课程讲解的处理器,所以你们很多人可能已经知道了RISC-V指令集。理论上,你可以在一个RISC-V计算机上运行XV6,已经有人这么做了。但是我们会在一个QEMU模拟器上运行XV6。

我这里会写下来,我们的操作系统是XV6,它运行在RISC-V微处理器上,当然不只是RISC-V微处理器,我们假设有一定数量的其他硬件存在,例如内存,磁盘和一个console接口,这样我们才能跟操作系统进行交互。但是实际上,XV6运行在QEMU模拟器之上。这样你们都能在没有特定硬件的前提下,运行XV6。

接下来,我会展示一下代码。首先,我会在我的笔记本上设置好XV6。首先输入make qemu,你会发现你在实验中会经常用到这个命令。这个命令会编译XV6,而XV6是用C语言写的。我首先执行一下make clean,这样你们就能看到完整的编译过程。

之后我输入make qemu,这条指令会编译并构建xv6内核和所有的用户进程,并将它们运行在QEMU模拟器下。

编译需要花费一定的时间。

现在xv6系统已经起来并运行了。$表示Shell,这是参照Unix上Shell的命令行接口。如果你用过Athena工作站,它的Shell与这里的非常像。XV6本身很小,并且自带了一小部分的工具程序,例如ls。我这里运行ls,它会输出xv6中的所有文件,这里只有20多个。

可以看到,这里还有grep,kill,mkdir和rm,或许你们对这些程序很熟悉,因为它们在Unix中也存在。

我向你们展示的第一个系统调用是一个叫做copy的程序。

它的源代码只有不到一页。你们这里看到的是一个程序,它从第8行的main开始,这是C程序的风格。它在第12行进入到一个循环中,在循环中,它会在第13行从输入读取一些数据,并在第16行,将数据写入到输出。如果我在XV6中运行这个copy程序,

它会等待输入。我随便输入一些字符,程序会读取我输入的字符,并将相同的字符输出给我。

所以这是一个非常简单的程序。如你所看到的,这个程序是用C语言写的,如果你不懂C语言,那最好还是去读一本标准的C编程语言。这个程序里面执行了3个系统调用,分别是read,write和exit。

如果你看第13行的read,它接收3个参数:

  • 第一个参数是文件描述符,指向一个之前打开的文件。Shell会确保默认情况下,当一个程序启动时,文件描述符0连接到console的输入,文件描述符1连接到了console的输出。所以我可以通过这个程序看到console打印我的输入。当然,这里的程序会预期文件描述符已经被Shell打开并设置好。这里的0,1文件描述符是非常普遍的Unix风格,许多的Unix系统都会从文件描述符0读取数据,然后向文件描述符1写入数据。
  • read的第二个参数是指向某段内存的指针,程序可以通过指针对应的地址读取内存中的数据,这里的指针就是代码中的buf参数。在代码第10行,程序在栈里面申请了64字节的内存,并将指针保存在buf中,这样read可以将数据保存在这64字节中。
  • read的第三个参数是代码想读取的最大长度,sizeof(buf)表示,最多读取64字节的数据,所以这里的read最多只能从连接到文件描述符0的设备,也就是console中,读取64字节的数据。

read的返回值可能是读到的字节数,在上面的截图中也就是6(xyzzy加上结束符)。read可能从一个文件读数据,如果到达了文件的结尾没有更多的内容了,read会返回0。如果出现了一些错误,比如文件描述符不存在,read或许会返回-1。在后面的很多例子中,比如第16行,我都没有通过检查系统调用的返回来判断系统调用是否出错,但是你应该比我更加小心,你应该清楚系统调用通常是通过返回-1来表示错误,你应该检查所有系统调用的返回值以确保没有错误。

如果你想知道所有的系统调用的参数和返回值是什么,在XV6书籍的第二章有一个表格。

学生提问:如果read的第三个参数设置成1 + sizeof(buf)会怎样?
Robert教授:如果第三个参数是65字节,操作系统会拷贝65个字节到你提供的内存中(第二个参数)。但是如果栈中的第65个字节有一些其他数据,那么这些数据会被覆盖,这里是个bug,或许会导致你的代码崩溃,或者一些异常的行为。所以,作为一个程序员,你必须要小心。C语言很容易写出一些编译器能通过的,但是最后运行时出错的代码。虽然很糟糕,但是现实就是这样。

有一件事情需要注意的事,这里的copy程序,或者说read,write系统调用,它们并不关心读写的数据格式,它们就是单纯的读写,而copy程序会按照8bit的字节流处理数据,你怎么解析它们,完全是用应用程序决定的。所以应用程序可能会解析这里的数据为C语言程序,但是操作系统只会认为这里的数据是按照8bit的字节流。

net.conn read 判断数据读取完毕_1.5 read, write, exit系统调用相关推荐

  1. net.conn read 判断数据读取完毕_高并发:缓存模式以及缓存的数据一致性

    缓存由于其高性能,支持高并发的特性,在高并发的项目中不可或缺.被大家广泛使用的有Redis,Memcached等.本文主要探讨几种常见的缓存的读写模式,以及如何来保证缓存和数据库的数据一致性. 这里大 ...

  2. net.conn read 判断数据读取完毕_单方验方|如何应对千万级工商数据抓取(一)

    最近主要在处理有关企业信用的工商数据库,朋友列出的名单在200万家上下,字段共有13个维度,数据规模粗略计算好几千万了.起初自己懵懵懂懂的爬了200万,经过不断调试改进,发现大规模抓取数据门门道道还真 ...

  3. python获取键盘输入_python之判断数据异常Python读取键盘输入

    Python提供了两个内置函数从标准输入读入一行文本,默认的标准输入是键盘.如下: <python之判断数据异常Python读取键盘输入>总结了关于python网站教程,对于我们来www. ...

  4. caffe代码阅读8: Data_layers的实现细节(各个数据读取层的实现细节) 2016.3.25-28

    一.Data_layers.hpp文件的作用简介 Data_layers.hpp在目前caffe的master分支中已经不能存在了,分散到各个文件中去了. 而之前是存在于cafferoot\inclu ...

  5. pandas数据读取处理详解

    文章目录 数据读取 read_table:读取txt文本文件 逐块读取 read_excel:读取excel文件 读取一个工作簿下多个sheet:ExcelFile类 read_fwf:读取固定宽度文 ...

  6. 【Pandas总结】第二节 Pandas 的数据读取_pd.read_csv()的使用详解(非常全面,推荐收藏)

    使用pandas进行数据读取,最常读取的数据格式如下: NO 数据类型 说明 使用方法 1 csv, tsv, txt 可以读取纯文本文件 pd.read_csv 2 excel 可以读取.xls . ...

  7. 『TensorFlow』数据读取类_data.Dataset

    一.资料 参考原文: TensorFlow全新的数据读取方式:Dataset API入门教程 API接口简介: TensorFlow的数据集 二.背景 注意,在TensorFlow 1.3中,Data ...

  8. python读取dat数据anaconda_基于python的大数据分析-pandas数据读取(代码实战)

    我们常见的数据存储格式无非就是csv.excel.txt以及数据库等形式. 数据读取 在pandas中可以使用一些函数完成数据的读取.比如read_csv.read_excel.read_table. ...

  9. 【Android FFMPEG 开发】FFMPEG 读取音视频流中的数据到 AVPacket ( 初始化 AVPacket 数据 | 读取 AVPacket )

    文章目录 I . FFMPEG 获取 AVPacket 数据前置操作 II . FFMPEG 获取 AVPacket 数据流程 III . FFMPEG AVPacket 结构体 IV . AVPac ...

最新文章

  1. BZOJ1002 [FJOI2007]轮状病毒(最小生成树计数)
  2. python unix时间戳转换成时间_关于python:将unix时间戳字符串转换为可读日期
  3. rust(51)-rust工具,prelude
  4. 最强整理!字节跳动历年Android中高级面试题全收录!附超全教程文档
  5. php选择排序从大到小,PHP选择排序
  6. SAP License:作业费用分割均分常见原因
  7. Python中self的用法详解(链接传送)
  8. xulrunner下载连接
  9. 基于JSP小型超市管理系统
  10. 阮一峰:炫耀从来不是我的动机,好奇才是(图灵访谈)
  11. 液晶面板里面有些什么配件_液晶显示器参数和部件详细介绍
  12. JAVA 如何使用File类创建文件,文件夹
  13. 嵌入式操作系统和RTOS(实时操作系统)介绍。
  14. Tomcat8源码解析
  15. Leetcode286墙与门
  16. 选择登山鞋,千万别买小了哦!
  17. M5 Forecasting - Accuracy:Multi-time series prediction with prophet
  18. 64位时间戳 php,32 位 PHP 时间戳问题
  19. 7-6 个税查询 (15 分)
  20. linux自动创建分区,shell编程 自动创建分区

热门文章

  1. 部署WSE3.0实战:性能、证书与WSE910错误
  2. Java多线程编程:变量共享分析(Thread)
  3. 数据管理技术的发展过程
  4. 网络爬虫--15.【糗事百科实战】多线程实现
  5. Linux--安装yum源
  6. VS toolTip1控件的使用1
  7. shell 需要注意的点
  8. 基于bootstrap框架在ie8以下,兼容媒体查询[css样式]
  9. Migrate Instance 操作详解 - 每天5分钟玩转 OpenStack(40)
  10. Java的几个同步辅助类