Grundlegendes zum gleichzeitigen Schreiben von Dateien aus mehreren Prozessen
Von hier :Ist die Datei unter UNIX atomar angehängt?
Stellen Sie sich einen Fall vor, in dem mehrere Prozesse dieselbe Datei öffnen und an sie anhängen. O_APPEND garantiert, dass die Suche bis zum Ende der Datei und der Beginn des Schreibvorgangs atomar sind. Somit können mehrere Prozesse an dieselbe Datei angehängt werden, und kein Prozess überschreibt den Schreibzugriff anderer Prozesse, sofern die Schreibgröße <= PIPE_BUF ist.
Ich habe ein Testprogramm geschrieben, in dem mehrere Prozesse geöffnet und in dieselbe Datei geschrieben werden (write(2)
). Ich stelle sicher, dass jede Schreibgröße> PIPE_BUF (4k) ist. Ich hatte damit gerechnet, Fälle zu sehen, in denen ein Prozess die Daten eines anderen überschreibt. Aber das passiert nicht. Ich habe mit verschiedenen Schreibgrößen getestet. Ist das nur Glück oder gibt es einen Grund, warum das nicht passiert? Mein letztendliches Ziel ist es zu verstehen, ob mehrere Prozesse, die an dieselbe Datei angehängt werden, ihre Schreibvorgänge koordinieren müssen.
Hier ist das komplette Programm. Jeder Prozess erzeugt einen int-Puffer und füllt alle Werte mit seinemrank
, öffnet eine Datei und schreibt darauf.
Technische Daten: OpenMPI 1.4.3 unter Opensuse 11.3 64-Bit
Kompiliert als: mpicc -O3 test.c, ausgeführt als: 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;
}