複数のプロセスが同じファイルを開いてそれに追加する場合を考えてみましょう。O_APPENDは、ファイルの終わりまでシークしてから書き込み操作を開始することがアトミックであることを保証します。したがって、複数のプロセスが同じファイルに追加でき、各書き込みサイズが<= PIPE_BUFである限り、他のプロセスの書き込みを上書きするプロセスはありません。
複数のプロセスを開いて同じファイルに書き込むテストプログラムを作成しました(write(2)
)。各書き込みサイズが>PIPE_BUF(4k)であることを確認します。プロセスが他の誰かのデータを上書きするインスタンスが表示されることを期待していました。しかし、それは起こりません。さまざまな書き込みサイズでテストしました。それは運だけですか、それともそれが起こらない理由がありますか?私の最終的な目標は、同じファイルに追加する複数のプロセスが書き込みを調整する必要があるかどうかを理解することです。
これが完全なプログラムです。すべてのプロセスはintバッファーを作成し、すべての値をそのバッファーで埋めrank
、ファイルを開いて書き込みます。
仕様:OpenSUSE11.364ビットのOpenMPI1.4.3
コンパイル: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;
}