第3章 文件I/O(3)_内核数据结构、原子操做

2021年09月15日 阅读数:3
这篇文章主要向大家介绍第3章 文件I/O(3)_内核数据结构、原子操做,主要内容包括基础应用、实用技巧、原理机制等方面,希望对大家有所帮助。

3. 文件I/O的内核数据结构编程

(1) 内核数据结构表数据结构

数据结构app

主要成员ide

文件描述符表函数

①文件描述符标志spa

②文件表项指针命令行

文件表项指针

①文件状态标志(读、写、追加、同步和非阻塞等状态标志)blog

②当前文件偏移量进程

③i节点表项指针

④引用计数器

i节点

①文件类型和对该文件的操做函数指针

②当前文件长度

③文件全部者

④文件所在设备、文件访问权限

⑤指向文件数据在磁盘块上所在位置的指针等。

(2)3张表的关系

 第3章 文件I/O(3)_内核数据结构、原子操做_文件锁

4. 文件的原子操做

(1)文件追加

  ①打开文件时使用O_APPEND标志,进程对文件偏移量调整数据追加成为原子操做至关于write函数将如下3个操做做为一个原子操做,不可被打断。

    A.从i节点读取文件长度做为当前偏移量

    B.往文件中写入数据

    C.修改i节点中文件长度信息等

  ②内核每次对文件写以前,都将进程的当前偏移量设置为该文件的尾端。这样再也不须要lseek来调整偏移量。

(2)文件建立

  对open函数的O_CREAT和O_EXCL的使用,而该文件存,open将失败,不然建立该文件,而且使得文件是否存在的断定建立过程成为原子操做

【编程实验】原子操做

//file_append.c

#include <unistd.h>
#include <stdio.h>
#include <stdlib.h> //exit
#include <string.h> //strlen
#include <fcntl.h>  //O_WRONLY

//为了演示文件定位与追加数据是否被打断,须要打开该程序的两个进程,分别按
//文件的格式在命令行中输入相应的参数。

int main(int argc, char* argv[]){
    if( argc < 3){
        printf("usage: %s content destfile\n", argv[0]);
        exit(1);
    }

    //注意,Linux默认下文件锁是建议锁(具体见后面“文件锁”方面的内容),因此
    //尽管加了O_WRONLY,但不一样进程仍然能够同时修改这个文件)
    //int fd = open(argv[2], O_WRONLY); //这种方式的定位与追加不是原子操做的
    int fd = open(argv[2], O_WRONLY | O_APPEND); //定位与追加是原子操做
    
    if(fd < 0){
        perror("open error");
        exit(1);
    }

    //定位到文件尾部(只使用O_WRONLY选项时,需手动定位到文件末尾
    //lseek(fd, 0L, SEEK_END);

    sleep(10); //为了把定位与写入过程隔开,以便演示多进程同时写入同一文件
               //时会出现后启动进程格覆盖以前进程写过的内容。
               
    //往文件尾部追加内容
    size_t size = strlen(argv[1])*sizeof(char);
    if(write(fd, argv[1], size)!=size){
        perror("write error");
        exit(1);
    }

    close(fd);

    return 0;
}