fcntl を使ったファイルロック
fcntl を使ったファイルロックであれば、NFS上のファイルでもロックできる(らしい。)
以下はテストコード。
#include <unistd.h> #include <stdlib.h> #include <stdio.h> #include <fcntl.h> #include <sys/stat.h> int main(int args, char** argv ){ int file_desc; struct flock region; file_desc = open( argv[1], O_RDWR | O_CREAT, 0666); struct stat buf; fstat(file_desc, &buf); region.l_type = F_WRLCK; region.l_whence = SEEK_SET; region.l_start = 0; region.l_len = buf.st_size; int res; int retry = 50; while( retry-- > 0 ){ res = fcntl(file_desc, F_SETLK, ®ion); if(-1 != res){ break; } printf("pid %d is waiting\n", getpid()); fflush(stdout); sleep(1); } //Critical section int count = 5; while( count-- > 0 ){ printf("pid %d has file lock\n", getpid()); fflush(stdout); sleep(2); } close(file_desc); return 0; }
第一引数にロックしたいファイルのパスを指定する。2つ同時に起動すると、ファイルロックしている様子が確認できる。
# ./fcntl fcntl.BAK & [1] 3167 pid 3167 has file lock # ./fcntl fcntl.BAK & pid 3168 is waiting [2] 3168 pid 3168 is waiting pid 3167 has file lock pid 3168 is waiting pid 3168 is waiting pid 3167 has file lock pid 3168 is waiting pid 3168 is waiting pid 3167 has file lock pid 3168 is waiting pid 3168 is waiting pid 3167 has file lock pid 3168 is waiting pid 3168 is waiting pid 3168 has file lock pid 3168 has file lock pid 3168 has file lock pid 3168 has file lock pid 3168 has file lock [1]- Done ./fcntl fcntl.BAK [2]+ Done ./fcntl fcntl.BAK