c - 了解来自多个进程的并发文件写入

标签 c unix file-io operating-system mpi

从这里:Is file append atomic in UNIX

考虑多个进程打开同一个文件并附加到它的情况。 O_APPEND 保证查找到文件末尾然后开始写操作是原子的。因此,多个进程可以附加到同一个文件,并且只要每个写入大小 <= PIPE_BUF,任何进程都不会覆盖任何其他进程的写入。

我编写了一个测试程序,其中多个进程打开并写入同一个文件 (write(2))。我确保每个写入大小 > PIPE_BUF (4k)。我期待看到进程覆盖其他人数据的实例。但那不会发生。我测试了不同的写入大小。这只是运气还是没有发生的原因? 我的最终目标是了解附加到同一文件的多个进程是否需要协调它们的写入。

这是完整的程序。每个进程创建一个 int 缓冲区,用它的 rank 填充所有值,打开一个文件并写入它。

规范: OpenMPI 1.4.3 上 Opensuse 11.3 64 位

编译为:mpicc -O3 test.c, 运行为:mpirun -np 8 ./a.out

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

int 
main(int argc, char** argv) {
    int rank, size, i, bufsize = 134217728, fd, status = 0, bytes_written, tmp_bytes_written;
    int* buf;
    char* filename = "/tmp/testfile.out";

    MPI_Init(&argc, &argv);
    MPI_Comm_rank(MPI_COMM_WORLD, &rank);
    MPI_Comm_size(MPI_COMM_WORLD, &size);

    buf = (int*) malloc (bufsize * sizeof(int));   
    if(buf == NULL) {
        status = -1;
        perror("Could not malloc");
        goto finalize;
    }
    for(i=0; i<bufsize; i++) 
        buf[i] = rank;

    if(-1 == (fd = open(filename, O_APPEND|O_WRONLY, S_IWUSR))) {
        perror("Cant open file");
        status = -1;
        goto end;
        exit(-1);
    }

    bytes_written = 0;
    if(bufsize != (tmp_bytes_written = write(fd, buf, bufsize))) {
        perror("Error during write");
        printf("ret value: %d\n", tmp_bytes_written);
        status = -1;
        goto close;
    }

close:
    if(-1 == close(fd)) {
        perror("Error during close");
        status = -1;
    }
end:
    free(buf);
finalize:
    MPI_Finalize();
    return status;
}

最佳答案

小于 PIPE_BUF 的写入原子性仅适用于管道和 FIFO。对于文件写入,POSIX 表示:

This volume of POSIX.1-2008 does not specify behavior of concurrent writes to a file from multiple processes. Applications should use some form of concurrency control.

...这意味着您只能靠自己了 - 不同的类 UNIX 将提供不同的保证。

关于c - 了解来自多个进程的并发文件写入,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12942915/

相关文章:

c - C程序中循环后的反向输出

c - mq_open() - EACCES,权限被拒绝

c - 父进程跟踪子进程的终止状态

bash - unix shell 脚本 - jot -r 1 1 4 是什么意思?我可以用 seq 替换 jot 吗?

java - 创建文件的最简单方法是什么?

c - 为什么这个编译器屏障不强制排序?

c - 为什么 'z'中存储的值为35?难道不应该是20吗,因为在函数 'c=*b'中(c等于*b指向的值)?

bash 脚本将参数回显到单独的行中

c - 从c中的文件中读取2个整数

linux - 从/dev/block/mmcblk0 和/dev/block/mmcblk0p1 读取的区别