文件IO、标准IO的区别及其效率

系统IO:Unix/Linux下的系统文件IO,即文件访问机制不经过操作系统内核的缓存,数据直接在磁盘和应用程序地址空间进行传输。

标准IO:带缓存的IO,又称为标准IO(C标准库中提供了标准IO库,即stdio),它实现了跨平台的用户缓存解决方案。
 

文件IO 和 标准IO的概念

【文件I/O】

        文件I/O是操作系统封装了一系列open、close、write、read等API函数构成的一套用来读、写文件的接口供应用程序使用,通过这些接口可以实现对文件的读写操作,但是效率并不是最高的。

        文件I/O是采用系统直接调用的方式,因此当使用这些接口对文件进行操作时,就会立刻触发系统调用过程,即向系统内核发出请求之后,系统内核会收到执行相关代码处理的请求,决定是否将操作硬件资源或返回结果给应用程序。

【标准I/O】

        标准IO:应用层C语言库函数提供了一些用来做文件读写的函数列表,叫标准IO。标准IO有一系列的C库函数构成(fopen,fclose,fwrite,fread),这些标准IO函数其实是由文件IO封装而来的(fopen内部还是调用了open);,我们通过fwrite写入的内容不是直接进入内核中的buf,而是先进入应用层标准IO库自己维护的buf中,然后标准IO库自己根据操作系统单次write的最佳count来选择好的时机来完成write到内核中的buf中。因此,标准I/O封装了底层系统调用更多的调用函数接口。

文件I/O和标准I/O的本质区别:

        1)缓冲区:标准I/O函数接口在对文件进行操作时,首先操作缓存区,等待缓存区满足一定的条件时,然后再去执行系统调用,真正实现对文件的操作。        而文件I/O不操作任何缓存区,直接执行系统调用。

        2)系统开销:使用标准I/O可以减少系统调用的次数,提高系统效率。例如,将数据写入文件中,每次写入一个字符。采用文件I/O的函数接口,每调用一次函数写入字符就会产生一次系统调用。        而执行系统调用时,Linux必须从用户态切换到内核态,处理相应的请求,然后再返回到用户态,如果频繁地执行系统调用会增加系统的开销。

        3)执行效率:采用标准I/O的函数接口,每调用一次函数写入字符,并不着急将字符写入文件,而是放到缓存区保存,之后每一次写入字符都放到缓存区保存。直到缓存区满足刷新的条件(如写满)时,再一并将缓存区中的数据写入文件,执行一次系统调用完成此过程,这样便很大程度地减少了系统的调用次数,提高了执行效率。

 文件IO、标准IO的区别及其效率_第1张图片

可以使用 time 命令测试 系统IO 和 标准IO程序执行效率,比如写 100 0000个数到某文件中。

文件IO、标准IO的区别及其效率_第2张图片

time命令:程序执行时加上time能够粗略统计程序执行过程中的耗时。通常会有三个值real time, user time和sys time.

1. real time
概念:程序从开始到结束所经历的时间,也就是用户所感受到的时间。包括当前程序CPU的用时和所有延迟程序执行的因素的耗时总和(比如其他程序耗时,等待I/O完成耗时等)。

来源:real time是由gettimeofday()中结束时间与开始时间相减得来。

2. user time
概念:程序执行过程中在用户空间(user space)中所花费的所有时间,即程序用户模式下的CPU耗时。

仅指当前进程。
其他进程的时间和当前进程I/O阻塞的时间均不计在内。
来源:user time是由wait()或times()系统调用得来。
3. sys time
概念:程序执行过程中内核空间(kernel space)中所花费的时间,即程序在内核调用中的CPU耗时。

仅指当前进程。
程序的库代码调用仍然是在用户空间下。
来源:sys time是由wait()或times()系统调用得来。

time 命令应用详解: Linux系统-real/user/sys time - kakaisgood - 博客园

        Real 是时钟时间-程序从开始至结束的总时间。他包括期间其他进程所占用的时间片和进程被阻塞的时间(如IO等待的时间)

        User 被测试程序在用户模式下所花的CPU时间。他是进程执行的正真的CPU时间。其他进程调度的时间片以及阻塞(如IO)的时间不包含在内。

        Sys 是进程在内核中所花费的CPU时间。他表示进程在内核调用中所花的CPU时间,而程序的库调用仍然运行在用户空间下。

User+Sys表示程序所执行的CPU时间(不包括IO以及其他进程的CPU时间).

系统IO速度快还是标准IO速度快呢

—— 标准IO比系统IO快了好多,原因是:
标准IO比系统IO多了一个缓存区。当我们将数据输入时,他不会马上将数据写入文件,而是会将数据先写入缓存区,之后一次性写入很多数据。而系统IO没有缓存区,所以他每次都要在数据和文件之间来回搬运所以增加了很大的工作量。

解决方法
手动的为系统IO加上一个缓存区,即使用dup2() 函数制定一个带缓冲区的文件描述符即可。

系统IO和标准IO的速度对比_抹布吸的博客-CSDN博客


#include

int dup2(int oldfd, int newfd);

dup2可以用参数newfd指定新文件描述符的数值。若参数newfd已经被程序使用,则系统就会将newfd所指的文件关闭,若newfd等于oldfd,则返回newfd,而不关闭newfd所指的文件。dup2所复制的文件描述符与原来的文件描述符共享各种文件状态。共享所有的锁定,读写位置和各项权限或flags等

dup()、dup2() 函数详解如下:

linux c——dup( )和dup2( )函数详解_tiandc的博客-CSDN博客_dup2

这里也有一篇很好的总结,记录下:系统调用IO和标准IO - 原野追逐 - 博客园

https://www.cnblogs.com/songhe364826110/p/11546076.html

你可能感兴趣的:(工作问题,_03_linux应用编程,c语言,c++,c#)