汽车网站建设规划书,品牌建设实施方案,资源软件库,做网站建设公司赚钱Linux的系统I/O函数#xff08;read、write、open、close和 lseek等#xff09;与C语言的C库函数#xff08;libc.so库文件中#xff09;都是相对应的#xff0c;它们都是动态库函数。如下图所示#xff0c;C库函数有fopen、fclose、fwrite、fread和fseek等。这些C库函数… Linux的系统I/O函数read、write、open、close和 lseek等与C语言的C库函数libc.so库文件中都是相对应的它们都是动态库函数。如下图所示C库函数有fopen、fclose、fwrite、fread和fseek等。这些C库函数都封装在libc.so库文件中其中的fopen函数用于打开一个文件其返回值为FILE *类型指向FILE类型的一个指针FILE类型为一个结构体用于描述对打开的文件的一些操作对于除了fopen以外的C库函数都会通过这个FILE *类型指针对打开的文件进行操作。 FILE类型为一个结构体包括三个部分文件描述符、文件读写指针和I/O缓冲区。
文件描述符整型用于索引到对应的磁盘文件类似于FCB文件控制块和索引结点包含了该文件在磁盘上的位置信息。对于每一个进程打开的所有文件在其PCB中都有记录相应的文件描述符如0代表标准输入其宏定义为STDIN_FILENO#define STDIN_FILENO 0。所有执行I/O操作的系统调用都以文件描述符即一个非负整数来指代所打开的文件。文件描述符可以用来表示所有类型的已打开文件。同时多个文件描述符可以指向同一个打开文件因为有在不同进程中打开同一个文件的需求。
文件描述符是一个整型数文件描述符表是一个整型数组而在PCB中有一个指针指向文件描述符表的首地址因此根据PCB就可以找到对应的文件描述符而每一个文件描述符都对应一个FILE *的指针即可以根据文件描述符进一步找到FILE结构体该结构体保存了所打开文件的属性信息文件大小、I/O缓冲、读写指针、文件打开次数等等而这样的结构体每个文件都只有一份供所有打开该文件的进程共享而这些进程所不同的只是文件描述符不一样。FILE结构体的内容只有一份。FILE结构体类似inode而文件描述符类似简化的FCB。
每一个文件只有一个文件读写指针读写文件过程中指针的实际位置在文件读写时要时刻注意当前文件指针的位置。文件读写指针指向将要写入或读出的下一个地址。如果一个进程对文件正在进行写入此时另一个进程要读取该文件的数据需要利用fseek函数将文件读写指针置于文件的起始位置才能读取数据。
系统调用指操作系统提供给用户程序调用的一组接口接口函数来获得内核提供的服务。在实际中程序员使用的通常不是系统调用而应用程序接口API也称为系统调用编程接口接口函数可能要一个或者几个系统调用才能完成函数功能此函数通过c库libc实现如freadfopen等。
I/O缓冲区。每一个C库函数在对文件操作时都会有对应的I/O缓冲区I/O缓冲区属于内存的一部分位于用户空间默认大小为8KB即8192个Bytes。
以fgetc / fputc函数为例当用户程序第一次调用fgetc 读一个字节时fgetc函数可能通过系统调用进入内核读1K字节到I/O缓冲区中然后返回I/O缓冲区中的第一个字节给用户把读写位置指向I/O缓冲区中的第二个字符以后用户再调fgetc 就直接从I/O缓冲区中读取而不需要进内核了当用户把这1K字节都读完之后再次调用fgetc时fgetc 函数会再次进入内核读1K字节到I/O缓冲区中。C标准库之所以会从内核预读一些数据放 在I/O缓冲区中是希望用户程序随后要用到这些数据C标准库的I/O缓冲区也在用户空间直接从用户空间读取数据比进内核读数据要快得多。另一方面用户程序调用fputc通常只是写到I/O缓冲区中这样fputc 函数可以很快地返回如果I/O缓冲区写满了fputc 就通过系统调用把I/O缓冲区中的数据传给内核内核最终把数据写回磁盘或设备。有时候用户程序希望把I/O缓冲区中的数据立刻给内核让内核写回设备或磁盘这称为Flush操作对应的库函数是fflushfclose函数在关闭文件之前也会做Flush操作。
由上可以看出fgetc和fputc库函数在完成工作的过程中可能需要几个系统调用如将I/O缓冲区的数据写入内核缓冲将内核缓冲数据刷到磁盘上等。因此通过增设I/O缓冲区和内核缓冲可以减少进入内核的次数和对磁盘的操作次数这些都需要系统调用来完成从而提高了读写效率。相对于内存机械硬盘的读写速度很慢。机械硬盘的读写寻道时间ms级而内存的读写速度是ns级别。另外从用户空间I/O缓冲区直接读写数据也会比进入内核系统调用要快很多。
Flush操作。指把I/O缓冲区的数据立即传送给内核然后刷到磁盘上分为强制性和非强制性两种。C库函数fflush是强制性把I/O缓冲区的数据立即写给内核的缓冲区C库函数fsync是强制性把内核缓冲区的数据立即刷到磁盘上。main函数的return和调用main函数中的exit退出当前进程也会把缓冲区的数据立即写到磁盘上。I/O缓冲区已经写满或者关闭文件时将会自动将其数据写到磁盘上。
内核缓冲区。人生三大错觉之中的一个在调用函数write()时我们觉得该函数一旦返回数据便已经写到了文件里可是这样的概念仅仅是宏观上的。实际上操作系统实现某些文件I/O时如磁盘文件为了保证I/O的效率在内核一般会用到一片专门的区域内存或独立的I/O地址空间作为I/O数据缓冲区.它用在输入输出设备和CPU之间用来缓存数据使得低速的设备和快速的CPU可以协调工作避免低速的输入输出设备长时间占用CPU降低系统调用提高了CPU的工作效率。
Linux系统I/O函数是没有I/O缓冲区的其缓存是由用户提供的。C库函数都有对应的I/O缓冲区8KB8196Bytes。注意内核缓冲和I/O缓冲的作用不同。