目录

一. 系统调用

1.1 什么是系统调用

二. open/close函数

2.1 open函数

2.2 close函数

2.3 open函数常见的三种错误

三. read/write函数

3.1 read函数

3.2 write函数

3.3 使用read与write实现命令cp

四.系统调用与库函数的比较

4.1 使用fputc与fgetc实现cp命令

4.2 预读入缓输出机制


一. 系统调用

1.1 什么是系统调用

是由操作系统实现并提供外部应用程序的编程接口(Application Programming Interface,API)。是应用程序同系统之间数据交互的桥梁。

系统调用(内核提供的函数)       

操作系统的本质的程序,代码,而操作系统的核心程序叫内核

只有系统调用才能进入内核空间!!!

例如:“hello”如何打印在屏幕上

实际上:其实write函数并不是真正的系统调用,而只是sys_write做了一层浅封装,sys_write才是真正的系统调用,write可以称其为系统函数。

二. open/close函数

2.1 open函数

函数原型:

描述:函数会打开由路径名指定的文件,若文件不存在,在某些情况下会创建文件。

返回值:成功返回一个文件描述符

              失败返回-1并且设置errno

参数flags:这些宏在头文件<fcntl.h>

O_RDONLY 只读
O_WRONLY 只写
O_RDWR 读写
O_APPEND 追加
O_CREAT 不存在则创建
O_EXCL 是否存在
O_TRUNC 截断(有数据则清空)
O_NONBLOCK 非阻塞

参数mode:(是一个八进制数)创建文件时,指定文件的访问权限。权限受umask的影响。结论是:

文件权限=mode & ~umask

umask是0002(一个八进制数)

eg:

可得mode取0644,文件权限是:rw- r-- r--

                取0664,文件权限是:rw- rw- ---

2.2 close函数

函数原型:

描述:关闭打开的一个文件描述符

返回值:成功返回0        失败返回-1并且设置error

2.3 open函数常见的三种错误

1、打开的文件不存在

2、以写的方式打开只读文件

3、以只写的方式打开目录

三. read/write函数

3.1 read函数

函数原型:

描述:从文件描述符fd中读取count字节的数据到缓冲区buf中。

返回值:成功:返回读取的字节数      0:表示读到结尾

               失败:返回-1并且设置error。(注意:还有另一种情况:返回-1且error是EAGAIN或EWOULDBLOCK,说明不是read失败,而是以非阻塞的方式读一个设备/网络文件,且文件里面无数据,这个需要另行判断!)

3.2 write函数

函数原型:

描述:从缓冲区buf中最多读取count字节的数据并且写入文件描述符fd中

返回值:成功:返回写入的字节数       0:表示没东西可写

               失败:返回-1并且设置error。

3.3 使用read与write实现命令cp

四.系统调用与库函数的比较

4.1 使用fputc与fgetc实现cp命令

这里使用命令strace来跟踪一个程序执行时所使用的系统调用:

这里可以看到虽然fgetc与fputc函数是一字节进行操作,但是所使用的系统调用确实以4096字节为单位进行操作。

再看看read与write这两个系统调用(为了与fgetc和fputc一致,将BUFSIZE设置为1)

这里可以看到read与write这两个系统调用是1字节进行操作的。

4.2 预读入缓输出机制

1、read与write

只有系统调用才能进入到内核空间。

从用户空间进入内核空间的时间消耗很大。

当在程序中将buf的大小设置为1时,read与write频繁的在用户区与内核区切换,故很慢。

故read、write这两个函数常被称为Unbuffered IO,无用户级缓冲区。

预读入与缓输出机制:从内核到磁盘之间的数据交互是一个物理操作,速度很慢,频繁操作会导致速度下降,图中红色的缓冲区是一个系统级缓存(大小一般是4096字节),当满时,一次性的写入磁盘,或者一次性从磁盘读出,避免了频繁的物理操作。

fputc与fgetc函数:

fputc与fgetc这两个库函数有一个自己的缓冲区(图中蓝色,默认4096大小),当使用这两个函数进行读写时,先读写到这个默认的缓冲区,满了之后一次性刷新,写入内核区,避免了在用户区与内核去之间频繁的切换,节省了时间。

Logo

openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构

更多推荐