第十三章

关于测定类的题目暂时跳过

13-1 使用shell内嵌的time命令,测算程序清单4-1 copy.c在当前环境下的用时。

a)使用不同的文件缓冲区大小进行试验。编译应用程序使用-DBUF_SIZE=NBYTES选项可以设置缓冲区大小。

b)对open的系统调用加入O_SYNC标志,针对大小不同的缓冲区,速度存在多大差异?

c)在一系列的文件系统中,例如ext3、XFS、Btrfs和JFS中执行这些测试,结果相同吗?当缓冲区大小变大时,用时趋势相同吗?

这里就不在验证了。不过可以肯定的是,read和write的性能和BUF_SIZE的大小是正相关的,当BUF_SIZE达到一定值后,几乎达到最优性能。

第二条,加入O_SYNC会导致性能降低,缓冲区越小降低的越厉害。

第三条,结果不同。不同的系统对调用到写入磁盘有不同的实现形式,这将导致性能差异。缓冲区增大时,趋势相同。因为过小的缓冲区会带来更多的系统调用和I/O开销。

13-2 测定filebuff/write_bytes.c程序在不同缓冲区以及文件系统大小下的用时。

这里不再测定了。理论上来说缓冲区越大用时越少。

13-3 如下语句执行的效果是什么?

fflush(fp);
fsync(fileno(fp));

强制刷新stdio缓冲区到内核缓冲区。然后强制将内核缓冲区数据写入磁盘。

13-4 下面的代码在标准输出和重定向到文件输出的结果顺序不同,为什么?

printf("If I had more time, \n");
write(STDOUT_FILENO, "I balabalaba.\n", 14);

这是因为当输出是终端时,每次遇到\n就会刷新stdio的缓冲区,所以内核缓冲区在之后才会接受第二句的内容。如果不是终端的话,而是文件,printf不会遇到\n刷新缓冲区,所以内核缓冲区可能首先接收到第二句的内容。

13-5 实现tail命令。该命令打印文件最后10行内容。

程序比较容易实现,通过lseek偏移至文件末尾,然后倒序读内容,读满特定个数个换行符'\n'之后,程序从当前位置将后面所有的内容度读入缓冲区,并一次性输出。下面是具体实现:

#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <fcntl.h>

int main(int argc, char *argv[])
{
    int lastLine = 10;
    char * path;
    if (argc == 4 && strcmp(argv[1], "-n") == 0)
    {
        lastLine = atoi(argv[2]);
        path = argv[3];
    }
    else if(argc == 2){
        path = argv[1];
    }
    else{
        printf("参数错误\n");
        return -1;
    }
    int fd = open(path, O_RDONLY);
    int end = lseek(fd, 0, SEEK_END);
    int count = 0;
    while(count < lastLine){
        char buff;
        int ret = lseek(fd, -1, SEEK_CUR);
        if(ret < 0) break;
        read(fd, &buff, 1);
        lseek(fd, -1, SEEK_CUR);
        if(buff == '\n'){
            count ++;
        }
    }
    int offset = lseek(fd, 0, SEEK_CUR);
    char * buff = malloc(end - offset);
    read(fd, buff, end - offset);
    printf("%s\n", buff + 1);
    return 0;
}

使用下面的命令编译运行代码:

gcc 13-5.c && ./a.out -n 5 13-5.c

之后,我们可以看到程序显示了文件最后的5行内容:

    char * buff = malloc(end - offset);
    read(fd, buff, end - offset);
    printf("%s\n", buff + 1);
    return 0;
}

results matching ""

    No results matching ""