如何使用fopen()locking文件?

我不知道是否有什么办法来locking和解锁Linux中的文件,当我打开一个文件使用fopen (不open )?

基于堆栈溢出问题C fopen vs openfopen优于open

如何通过创build和删除locking文件来实现自己的文件locking(如果可能)?

Solutions Collecting From Web of "如何使用fopen()locking文件?"

我坚决不同意fopen优先于open的说法。 因为没有O_EXCL选项,所以在由于符号链接漏洞/竞争条件而将文件写入其他用户可写的目录中时,不可能安全地使用fopen 。 如果你需要在POSIX系统上使用stdio,最好使用openfdopen而不是直接调用fopen

现在,至于锁定取决于你想要做什么。 POSIX没有像Windows那样的强制锁定,但是如果你只是想确保你正在处理一个新的文件,而不是打开一个已经存在的文件或者一个符号链接,那么根据需要使用O_EXCLO_NOFOLLOW选项。 如果你想在初始打开之后进行合作锁定,使用fcntl锁。

在Linux中,如果你需要一个文件描述符(例如,传递给一个文件锁定原语),你可以使用fileno(FILE*)来检索它。 检索文件描述符后,可以像使用open返回。

例如,而不是

 int fd = open("myfile.txt", flags); int result = flock(fd, LOCK_SH); 

你也可以这样做:

 FILE* f = fopen("myfile.txt", "r"); int result = flock(fileno(f)), LOCK_SH); 

请注意, fileno在POSIX标准中定义,但不在C或C ++标准中定义。

至于你的第二个问题,Linux的open()手册页有这样的说法:

使用lockfile执行原子文件锁定的解决方案是在同一个文件系统上创建一个唯一的文件(例如,包含主机名和pid),使用link(2)创建一个到lockfile的链接。 如果link()返回0,则锁定成功。 否则,在唯一文件上使用stat(2)来检查它的链接数是否增加到2,在这种情况下,锁也是成功的。

文件可以通过使用flock()来锁定。 它的语法是

  #include <sys/file.h> #define LOCK_SH 1 /* shared lock */ #define LOCK_EX 2 /* exclusive lock */ #define LOCK_NB 4 /* don't block when locking */ #define LOCK_UN 8 /* unlock */ int flock(int fd, int operation); 

首先使用fopen()open()文件。 然后这个打开的文件被锁定使用flock() ,如下所示

 int fd = open("test.txt","r"); int lock = flock(fd, LOCK_SH); // Lock the file . . . // . . . . // Locked file in use // . . . . int release = flock(fd, LOCK_UN); // Unlock the file . . . 

如果你想简单地实现你自己的锁,我建议Rob使用羊群的答案。 如果你希望以一种复杂的方式实现它,比如高可用性,你可以尝试一些东西,例如使用一个线程定期触摸一个文件。 所有其他程序想要锁定文件也应该检查文件,看看它的更新时间已经更新在另一个固定的,但更大的时间间隔(大部分是重要的)。 这对大多数应用程序来说可能是过度的,但它处理诸如崩溃,死机等事情要比群集好得多。

请注意,在下面的代码中,如果锁定文件/var/lock/my.lock不存在, fopen将会失败(并返回NULL)。

 FILE* f = fopen("/var/lock/my.lock", "r"); int result = flock(fileno(f)), LOCK_SH); 

如果需要创建锁定文件(如果不存在),请使用w+

 FILE* f = fopen("/var/lock/my.lock", "w+"); int result = flock(fileno(f)), LOCK_SH); 

open()函数的另一种方法,但我不确定这个被称为锁定的文件。 我正在使用文件权限来打开文件。

代码在这里:

 #include <stdio.h> #include <fcntl.h> #include <sys/stat.h> #include <sys/types.h> #define FILE_NAME "hello.txt" int main() { int fd; fd = open(FILE_NAME, O_CREAT, S_IRWXU); // Error checking if(fd == -1){ perror("[error]\n"); } else{ printf("[file is opened]\n"); } return 0; } 

我使用了权限标志(第三个参数)。 这个标志给予用户读,写和执行权限。

 $ls -alh total 24K drwxrwxr-x 2 arien arien 4.0K Dec 28 20:56 . drwxrwxr-x 18 arien arien 4.0K Dec 27 22:20 .. -rwxrwxr-x 1 arien arien 8.5K Dec 28 20:56 fopen -rw-rw-r-- 1 arien arien 290 Dec 28 20:56 fopen.c -rwx------ 1 arien arien 0 Dec 28 20:55 hello.txt 

小技巧:如果您使用的是Ubuntu或Debian,您可以使用man [function_name] 手册页的open()函数来查看函数的描述。