5233杨光--第十周学习总结

一、第十章知识点

***Unix I/O

Unix I/O:简单低级的应用接口,使所有输入输出都以统一的方式执行。

  • 打开文件。一个应用程序通过要求内核打开相应文件,来宣告它想要访问一个I/O设备,内核返回描述符(小的非负整数)。每个进程开始时都有三个打开的文件:标准输入(描述符为0)、标准输出(描述符为1)、标准错误(描述符为2)。
  • 改变当前的文件位置。每个打开的文件内核保持着一个文件位置k,初始为0。
  • 读写文件。读操作就是从文件拷贝n>0个字节到存储器,从当前文件位置k开始将k增加到k+n。
  • 关闭文件。将描述符恢复到可用的描述池中。

***打开和关闭文件

--open:进程通过调用open函数来打开一个已存在的文件或创建一个新文件。

#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>

int open(char *filename, int flags, mode_t mode);
返回:若成功则为新文件描述符,若出错则为-1。

open函数将filename转换为一个文件描述符,并返回描述符数字。返回的描述符是在进程中当前没有打开的最小描述符。

  flags参数指明进程打算如何访问这个文件:

  • O_RDONLY:只读
  • O_WRONLY:只写
  • O_RDWR:可读可写

  以只读的方式打开一个已存在的文件:

fd = Open("foo.txt, O_RDONLY, 0");

  打开一个已存在的文件,并在后面添加一些数据:

fd = Open("foo.txt, O_WRONLY|O_APPEND, 0");

-- close:进程通过调用close函数关闭一个打开的文件。

#include<unistd.h>
int close(int fd);
返回:若成功则为0,若出错则为-1。

关闭一个已关闭的描述符会出错。

***读和写文件

-- read和write函数:应用程序通过分别调用read和write函数来执行输入和输出。

#include<unistd.h>
ssize_t read(int fd, void *buf, size_t n);
返回:若成功则为读的字节数,若EOF则为0,若出错则为-1。
ssize_t write(int fd, const void *buf, size_t n);
返回:若成功则为写的字节数,若出错则为-1。
  • read函数从描述符为fd的当前位置拷贝最多n个字节到存储器位置buf。
  • write函数从存储器位置buf拷贝至多n个字节到描述符fd的当前文件位置。

注:"csapp.h"是《深入理解计算机系统》这本书写的头文件,运行代码时需要将该头文件下载并移到/usr/include中。

-- ssize_ t 和 size_t 的区别

  • size_t:read函数的输入参数,定义为unsigned int
  • ssize_t:read函数的返回值,定义为int。因为出错时必须返回-1。

***用RIO包健壮地读写

-- RIO包:自动处理不足值,提供两类不同的函数

  • 无缓冲的输入输出函数:直接在存储器和文件之间传送数据。
  • 带缓冲的输入函数:高效地从文件中读取文本行和二进制数据。

-- RIO的无缓冲的输入输出函数

应用程序通过调用rio_ readn和rio_ writen函数可以在存储器和文件之间直接传送数据。

#include"csapp.h"
ssize_ t rio_ readn(int fd, void *usrbuf, size_t n);
ssize_ t rio_ writen(int fd, void *usrbuf, size_t n);
返回:若成功则为传送的字节数,若EOF则为0(只对rio_ readn而言),若出错则为-1。

rio_ readn函数从描述符fd的当前文件位置最多传送n个字节到存储器位置usrbuf。rio_ writen函数从存储器位置usrbuf传送n个字节到描述符fd。

-- RIO的带缓冲的输入函数

一个文本行就是一个由换行符结尾的ASCII码字符序列。

调用包装函数rio_ readlineb,从一个内部读缓冲区拷贝一个文本行,当缓冲区变空时会自动调用read重新填满缓冲区。

#include"csapp.h"
void rio_ readlineb(rio_t *rp, int fd);
ssize_ t rio_ readlineb(rio_t *rp, void *usrbuf, size_t maxlen);
ssize_ t rio_ readnb(rio_t *rp, void *usrbuf, size_t n);
返回:若成功则为读的字节数,若EOF则为0,若出错则为-1。
  • rio_ readlineb函数从文件rp读出一个文本行(包括结尾的换行符),将它拷贝到存储器位置usrbuf,并用空(零)字符结束这个文本行。rio_ readlineb函数最多读maxlen-1个字节,余下一个字符留给结尾的空字符。
  • rio_ readnb函数从文件rp最多读n个字节到存储器位置usrbuf。对同一描述符,对rio_ readlineb和rio_ readnb的调用可以任意交叉进行。

***读取文件元数据

-- 应用程序能通过调用stat和fstat函数检索到关于文件的信息(元数据)。

#include<unistd.h>
#include<sys/stat.h>
int  stat(const char *filename, struct stat *buf);
int fstat(int fd, struct stat *buf);
返回:若成功则为0,若出错则为-1。

-- stat数据结构成员:st_ mode、st_ size……

st_ size成员包含了文件的字节数大小,st_ mode成员编码了文件访问许可位和文件类型。

***共享文件

-- 内核用三个相关的数据结构来表示打开的文件:

  • 描述符表
  • 文件表
  • v-node表

多个描述符可以通过不同的文件表表项来引用同一个文件。每个描述符都有它自己的文件位置,所以对不同描述符的读操作可以从文件的不同位置获取数据。

调用fork后,子进程有一个父进程描述符表的副本,共享相同的文件位置。在内核删除相应文件表项之前,父子进程必须都关闭它们的描述符。

***I/O重定向

I/O重定向操作符:允许用户将磁盘文件和标准输入输出联系起来。I/O重定向可使用dup2函数工作。

#include<unistd.h>
int dup2(int oldfd, int newfd);
返回:若成功则为非负的描述符,若出错则为-1。

dup2函数拷贝描述符表表项oldfd到描述符表表项newfd,覆盖描述符表表项newfd以前的内容。如果newfd已经打开了,dup2会在拷贝oldfd之前关闭newfd。

***标准I/O

标准I/O库提供打开和关闭文件的函数(fopen和fclose)、读和写字节的函数(fread和fwrite)、读和写字符串的函数(fgets和fputs),以及复杂的格式化的I/O函数(scanf和printf)。

***错误处理

-- 错误处理包装函数

定义:给定某个基本的系统级函数foo,定义一个有相同参数、只不过开头字母大写的包装函数Foo。包装函数调用基本函数并检查错误。如果包装函数发现错误,则打印一条信息并终止进程。否则它返回到调用者。

-- Unix系统中的错误处理

三种风格:

  • Unix风格的错误处理:遇到错误返回-1,成功则返回有用的结果。
  • Posix风格的错误处理:只用返回值来表明成功(0)或者失败(非0)
  • DNS风格的错误处理:失败时返回NULL指针,并设置全局变量h_errno

-- 错误处理包装函数

  • Unix风格:

    pid_t Wait(int *status)
    {
        pid_t pid;
        if(pid = wait(status)<0)
        unix_error("wait error");
        return pid;
    }
    
  • Posix风格:
    void Pthread_detach(pthread_t tid)
    {
        int rc;
        if(rc=pthread_detach(tid) != 0)
        posix_error(rc,"Pthread_detach error");
    }
    
  • DNS风格:
    struct hostent *Gethostbyname(const char *name)
    {
        struct hostname *p;
        if((p = gethostbyname(name)) == NULL)
            dns_error("Gethostbyname error");
        return p;
    }

二、课堂总结

***进程的定义

--什么是进程:一个执行中的程序的实例,系统中每个程序都运行在某个进程的上下文中。

--进程提供给应用程序的关键抽象

  • 一个独立的逻辑控制流
  • 一个私有的地址空间

***并发

--什么是并发:多个流并发的执行的一般现象称为并发(一段时间内P1、P2交替运行)

--并行流:并发流的真子集,两个流并发地运行在不同的处理器核或计算机上,并行地运行且并行地执行。

***进程控制

--获取进程ID

    #include<sys/types.h>
    #include<unistd.h>
    pit_t getpid(void);//返回调用进程的PID
    pit_t getppid(void);//返回它的父进程的PID

--创建和终止进程

进程三态:

  • 运行
  • 停止(进程的执行被挂起且不会被调度)
  • 终止(原因:①收到一个默认行为是终止进程的信号 ②从主程序返回 ③调用exit函数)

父进程通过调用fork函数创建一个新的运行子程序

    #include<sys/types.h>
    #include<unistd.h>
    pid_t fork(void);
    子进程返回0,父进程返回子进程的PID(大于0),出错返回-1。

注:父进程调用fork时,子进程可以读写父进程中打开的任何文件,父进程和新建的子进程最大的区别在于他们有不同的PID。

***fork函数

特点:只被调用一次,返回两次。一次在调用父进程中,返回子进程的PID;一次在新建的子进程中,返回0。

  • 并发执行:父进程和子进程是并发运行的独立进程,内核能以任意方式交替执行它们逻辑控制流中的指令。
  • 相同但独立的地址空间。
  •   共享文件

三、参考资料

《深入理解计算机系统》

《嵌入式Linux应用程序开发标准教程》

四、心得体会

  这周的任务就是复习上周所学的I/O知识,总结上课讲的进程知识。

我总结了fork函数的具体用法,理解了运行的过程。

这些知识让我不断地深入了解计算机,知其然,知其所以然。

 

时间: 2024-11-18 01:55:56

5233杨光--第十周学习总结的相关文章

第十周学习进度

  第十周 学习时间 15 代码量 300 博客量 1 学习到的知识点 安卓程序的编写,软件用户的需求分析 总结:这周比较轻松,主要是对自己程序后期开发的构想,理念,想法很重要,要符合面对用户的需求,要有自己的特色,这很重要.

信息安全设计基础第十周学习总结

信息安全设计基础第十周学习总结 [学习时间:8小时]  [学习内容:教材第十章 之 I/O总结:实验楼私有课程<深入理解计算机系统> 之 系统级I/O] 一.教材内容 1.I/O重定向 [重定向其实是unix系统优越性的一种体现(与管道相似):将一种操作的结果重定向到另外一种操作上,这样的思想保证了“专务专用”,将单个操作做到极致,又为用户自己提供了完善功能的平台(比如重定向,比如管道).] - unix外壳提供了I/O重定向操作符,允许用户将磁盘文件和标准输入输出连接起来.例如: ls &g

20145239 《信息安全系统设计基础》第十周学习总结

20145239 <信息安全系统设计基础>第十周学习总结 本周重点代码学习 代码cp1.c 进行复制文件的操作,要有原文件. 代码fileinfo.c 用来实现显示文件信息.先判断命令是否有操作数,有的话才能继续进行下去,如果没有报错就打印出来相关文件信息,报错就用perror将报错信息打印出来. filesize.c 用来查找文件的大小.(这个代码老师给的好像有些问题开始出了如下错误,修改后运行正常) echostate.c 用来检查命令行中的提示符是否显示的,如果显示,输入的命令都可见,不

20145311 《信息安全系统设计基础》第十周学习总结

20145311 <信息安全系统设计基础>第十周学习总结 代码调试中的问题和解决过程 cp 类似于cp的cp1命令,用来复制文件或目录 cp的关键步骤: 打开源文件 创建目标文件 把源文件读入缓冲区 把缓冲区内容写入目标文件 关闭源文件和目标文件 此外,代码中还包含了一些错误的提示,例如打开错误,创建错误,用法错误等 setecho & echostate 下图为设置echo为no之后键盘的输入不显示,但依然可以执行命令 当echo为no是 echostate显示为关闭状态 代码分析#

## 20155336 2016-2017-2《JAVA程序设计》第十周学习总结

20155336 2016-2017-2<JAVA程序设计>第十周学习总结 学习任务 完成学习资源中相关内容的学习 参考上面的学习总结模板,把学习过程通过博客(随笔)发表,博客标题"学号 2016-2017-2 <Java程序设计>第十周学习总结" 截止时间:本周日 24:00,不按时发博客要扣1分,优秀博客加1分 严禁抄袭,违反者列入立此存照-抄袭作业者的曝光台 学习内容总结 网络编程 网络编程就是在两个或两个以上的设备(例如计算机)之间传输数据.程序员所作的

20172313 2017-2018-2 《程序设计与数据结构》第十周学习总结

20172313 2017-2018-2 <程序设计与数据结构>第十周学习总结 教材学习内容总结 了解集合的同构和异构:同构集合保存类型全部相同的对象,异构集合可以保存各种类型的对象. 集合可以用各种方式实现,保存对象的基础数据结构可以用各种技术来实现. 学习动态结构,初步学习链表中的增删查改. 学习线性数据结构:队列(queue)先进先出,堆栈(stack)先进后出. 了解非线性数据结构:树(由一个根节点和构成层次结构的多个节点组成),图(连接一个图内各节点的边数一般没有限制). 了解Jav

20172310 2017-2018-2 《程序设计与数据结构》第十周学习总结

20172310 2017-2018-2 <程序设计与数据结构>第十周学习总结 教材学习内容总结 本周学习的是第十三章 集合与数据结构 集合是一种对象,类似于保存其他对象的存储库.我们常用集合表示一个专用于保存元素的对象,并且该对象还提供增添,删除等管理 所保存元素的服务. 集合是同构的,意味着这种集合保存类型全部相同的对象;另一些集合则是异构的,即这种集合可以保存各种类型的 对象. 分离接口与实现: 1.一个抽象数据类型(ADT)是由数据和在该数据上所实施的具体操作构成的集合.一个ADT有名

20172320 2017-2018-2 《Java程序设计》第十周学习总结

20172320 2017-2018-2 <Java程序设计>第十周学习总结 教材学习内容总结 1.集合是一种对象,类似于保存其他对象的存储库 - 集合的同构意味着这种集合保存类型全部相同的对象:异构意味着可以保存各种类型的对象 2.抽象数据类型(ADT)是由数据和在该数据上所实施的具体操作构成的集合. - ADT有名称.值域和一组允许执行的操作 - ADT上可以执行的操作与底层的实现分离开了 3.一个动态数据结构用链来实现,动态数据结构的大小规模随需要增长和收缩 4.线性数据结构 - 队列:

20172315 2017-2018-2 《程序设计与数据结构》第十周学习总结

20172315 2017-2018-2 <程序设计与数据结构>第十周学习总结 教材学习内容总结 集合是一种对象,类似于保存其他对象的存储库. 集合的同构和异构:同构意味着这种集合保存类型全部相同的对象,异构可以保存各种类型的对象. 对象具有定义良好的接口,从而成为一种实现集合的完整机制. 数据结构的动态表示:一个动态数据结构用链来实现,利用对象引用作为连接对象之间的链,就可以建立起适用于各种情况的数据结构.按这种方式建立的数据结构具有动态性,因为其大小是在使用时动态确定的,而不是在声明时静态