本习题设计的目的在于展示为何以O_APPEND标志打开文件来保障操作的原子性是必要的?

首先编写文件atomic_append.c:

/*##############################################
#
# Author: Lizhenggen  - 762741539@qq.com
#
# QQ : 762741539
#
# Last modified:        2022-04-17 15:23
#
# Filename:             atomic_append.c
##############################################*/

#include <stdio.h>
#include<unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include<sys/stat.h>
#include<string.h>
#include<fcntl.h>
#include<errno.h>


int main(int argc, char const *argv[])
{
    if(argc > 4 || 0 == strcmp(argv[1],"--help"))
    {
        printf("%s test write O_APPEND\n",argv[0]);
    }
    long long num_byte;
    char buf = 'x';
    int fd ;
    if(argc == 3)
    {
        fd = open(argv[1], O_CREAT|O_WRONLY|O_APPEND, 0666);
        num_byte = atoll(argv[2]);      //将字符串转化为longlong类型
        while (num_byte--)
        {
            if(-1 == write(fd,&buf,1))  //每次写入一个字节
            {
                perror("write");
            }
        }
        if(-1 == close(fd))
        {
            perror("close file");
        }
    }
    if(argc == 4)
    {
        fd = open(argv[1], O_CREAT|O_WRONLY, 0666);
        num_byte = atoll(argv[2]);
        while (num_byte--)
        {
            if(lseek(fd,0,SEEK_END) == -1)
            {
                perror("lseek");
            }
            if(-1 == write(fd,&buf,1)) //每次写入一个字节
            {
                perror("write");
            }
        }
        if(-1 == close(fd))
        {
            perror("close file");
        }
    }
    return 0;
}

编写Makefile文件:

LIBINCL = -I/apue/tlpi-book/lib
CPUBLIC = /apue/tlpi-book/lib/get_num.c /apue/tlpi-book/lib/error_functions.c


CFLAGS = -g


all : copy kongdong large_file o_appendtest atomic_append

copy : copy.c
        gcc $(CFLAGS) -o copy copy.c $(LIBINCL) $(CPUBLIC) -lm -lc
kongdong : kongdong.c
        gcc $(CFLAGS) -o kongdong kongdong.c $(LIBINCL) $(CPUBLIC) -lm -lc
large_file : large_file.c
        gcc $(CFLAGS) -o large_file large_file.c $(LIBINCL) $(CPUBLIC) -lm -lc
o_appendtest : o_appendtest.c
        gcc $(CFLAGS) -o o_appendtest o_appendtest.c $(LIBINCL) $(CPUBLIC) -lm -lc
atomic_append: atomic_append.c
        gcc $(CFLAGS) -o atomic_append atomic_append.c -lm -lc

clean:
        rm copy kongdong large_file o_appendtest atomic_append

然后编译运行程序,根据题目要求生成文件f1和f2,可以看出两个文件大小稍微有些区别,都是写入200万个字节,但是不带O_APPEND标志符的f2文件稍微小一点:
在这里插入图片描述
造成这种结果的原因就是使用lseek函数来将文件偏移指针移动写入到末尾,会出现写入覆盖,导致f2小于200万个字节。这也就说明了O_APPEND可以保证open函数的原子性。

posted @ 2022-04-17 15:31  一颗蘋果  阅读(17)  评论(0编辑  收藏  举报