Отсюда: Является ли приложение append атомарным в UNIX
Рассмотрим случай, когда несколько процессов открывают один и тот же файл и добавляют к нему. O_APPEND гарантирует, что поиск конца файла, а затем начало операции записи является атомарным. Таким образом, несколько процессов могут присоединяться к одному и тому же файлу, и ни один процесс не будет перезаписывать любые записи других процессов, поскольку каждый размер записи равен <= PIPE_BUF.
Я написал тестовую программу, в которой несколько процессов открываются и записываются в один и тот же файл (write(2)). Я уверен, что каждый размер записи составляет > PIPE_BUF (4k). Я ожидал увидеть случаи, когда процесс перезаписывает чужие данные. Но этого не происходит. Я тестировал с разными размерами записи. Это просто удача или есть причина, почему этого не происходит?
Моя конечная цель - понять, нужно ли координировать свои записи несколько процессов, добавляемых к одному файлу.
Вот полная программа. Каждый процесс создает внутренний буфер, заполняет все значения с помощью 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;
}