APUE学习笔记-文件共享

本文深入探讨了Unix系统中进程间文件共享的机制,详细解释了文件描述符、文件表和v节点的作用及其如何实现多个进程对同一文件的独立访问与偏移量控制。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

文件共享
Unix系统支持在不同的进程间共享打开文件。其结构如下所示:
在这里插入图片描述
内核使用了三种数据结构,它们之间的关系决定了在文件共享方面一个进程对另一个进程的影响。

  • 每个进程在进程表中都有一个记录项,在每个记录项中都有一张打开的文件描述符表,每个描述符占用一项。与每个文件描述符相关联的是:

    • 文件描述符,文件描述符;
    • 指向一个文件表项的指针
  • 内核为所有打开的文件维持一张文件表。每个文件表包含的信息如下:

    • 文件状态标志(读、写、同步、非堵塞等);
    • 当前文件的偏移量
    • 指向该文件v节点表项的指针
  • 每个打开的文件(或设备)都有一个v节点结构。v节点包含了文件类型和对此文件进行各种操作的函数的指针信息。对于大多数文件,还包括了i节点(索引节点)。这些信息在打开时,从磁盘上读入内存,所以所有的关于文件的信息都是快速可供使用的。例如,i节点包括了文件所有者、文件长度、文件所在的设备、指向文件在磁盘上所使用的实际数据块指针。

如果多个进程打开同一个文件,那么此时的共享结构如下:
在这里插入图片描述
如果两个独立进程各自打开了同一个文件,打开此文件的每一个进程得到一个文件表项,但对于一个给定的文件只有一个v节点表项。每个进程都有自己的文件表项的一个理由:这种安排使每个进程都有它自己对该文件的当前偏移量。

  • 在完成每个write之后,在文件表项中的当前文件偏移量就是当前所写入增加的字节数。如果这使当前文件的偏移量超过了当前文件的长度,则在i节点表项中的当前文件长度被设置为当前文件偏移量。
  • 如果使用O_APPEND标志打开一个文件,则相应标志也被设置到文件表项的文件状态标志中。每次对这种具有O_APPEND标志的文件执行写操作时,在文件表项中的当前文件偏移量首先被设置为i节点的文件长度。这就使得每次写数据都添加到文件的末尾。
  • lseek函数只是修改了文件表项的当前文件偏移量,没有进行I/O操作。
  • 若一个文件用lseek被定位到文件当前的末尾,则文件表项中当前文件偏移量被设置为i节点的当前文件长度。
    备注:
  • 可能多个文件描述符指向同一个文件表项;
  • 文件描述符和文件表项文件状态标志在作用范围是有区别的。文件描述符只用于一个进程的一个描述符,而后者则适用于指向该文件表项的任何进程中的所有描述符。
### APUE 第三章 学习笔记 #### 文件 I/O 基础 APUE 的第三章主要讨论了 Unix 系统中的文件 I/O 操作基础。这一章节涵盖了多个重要的概念和技术细节,对于理解如何高效地操作文件至关重要。 #### 打开和关闭文件 为了打开一个文件,程序通常会使用 `open` 或者 `creat` 函数[^1]。这两个函数都返回一个小于零的整数作为错误指示,而成功的调用则返回一个非负整数表示新创建的文件描述符。当不再需要访问某个特定文件时,应该通过调用 `close` 来关闭它。这不仅释放了与该文件关联的操作系统资源,而且也使得这个文件描述符能够被重新利用。 ```c #include <fcntl.h> /* For O_* constants */ #include <unistd.h> /* For open(), close() */ int fd; fd = open("example.txt", O_RDWR | O_CREAT, S_IRUSR | S_IWUSR); if (fd >= 0) { // File opened successfully. } // Later... close(fd); ``` #### 文件读写 一旦有了有效的文件描述符,就可以对其进行读取 (`read`) 和写入 (`write`) 操作。这些基本的 I/O 操作允许应用程序直接处理底层的数据流而不必关心具体的设备特性[^2]。 ```c char buffer[BUFSIZ]; ssize_t n; n = read(fd, buffer, BUFSIZ - 1); if (n > 0) { buffer[n] = '\0'; // Null terminate the string printf("%s\n", buffer); } const char *msg = "Hello world!"; write(fd, msg, strlen(msg)); ``` #### 文件定位 除了简单的顺序读写外,还可以改变当前文件偏移量来实现随机访问。这是通过 `lseek` 实现的功能之一,它可以向前或向后移动文件指针的位置以便从不同的位置开始读写数据[^3]。 ```c off_t offset; offset = lseek(fd, SEEK_SET, 0); // Move to beginning of file if (offset != -1L) { // Seek succeeded. } ``` #### 特殊文件类型的支持 Unix 系统支持多种特殊类型的文件对象,比如管道、套接字以及终端设备等。本章还介绍了针对这些不同类型文件的具体 API 接口和支持机制[^4]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值