繁体   English   中英

Linux文件锁定

[英]Linux file locking

问题:在Linux平台上创建新文件或覆盖现有文件,以便其他进程可以将其打开以供只读。 使用CreateFile可以执行以下操作:

CreateFile("blah.log", GENERIC_WRITE, FILE_SHARE_READ,
           NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);

如果另一个文件打开了具有类似标志的文件,则此调用将无法覆盖该文件。

如何在Linux上实现类似的行为? 假定所有程序都遵守咨询锁。

使用open和咨询性flock锁定,编写者需要持有LOCK_EX独占锁定。 读者不得持有任何锁,然后他们可能会看到文件突然被截断。

普通的fopen可以用于读者。 对于品行端正的作家,

#include <sys/types.h>
#include <sys/stat.h>
#include <sys/file.h>
#include <fcntl.h>
#include <stdio.h>

// never truncates
int fd = open("foo.log", O_CREAT|O_WRONLY /*or O_RDWR */, 0644 /* mode */);
if (flock(fd, LOCK_EX|LOCK_NB) != 0) {
    perror("Locking failed - I am not an exclusive writer");
    exit(1);
}

// I hold the exclusive lock - now, truncate the file to 0 bytes
ftruncate(fd, 0);

(为简便起见,省略了其他错误检查)

如果您希望对其中的文件使用<stdio.h>例程,则可以使用fdopen

// "w" will not truncate!
FILE *f = fdopen(fd, "w"); // or `r+` for O_RDWR...

请注意,读取器不得在文件上设置LOCK_SH锁,否则写入器将无法打开它。

您正在寻找flocklockf功能:)

大部分内容都是基于man 2 flockman lockf ,所以我衷心推荐阅读。

这是来自man lockf

 #include <unistd.h> int lockf(int fd, int cmd, off_t len); 

描述

在打开的文件的一部分上应用,测试或删除POSIX锁。 该文件由fd指定,文件描述符打开以供写入,操作由cmd指定,如果len为正,则该部分由字节位置pos..pos + len-1组成;如果len为len,则由pos-len..pos-1组成。为负,其中pos是当前文件位置,如果len为零,则此部分从当前文件位置延伸到无穷大,包括当前和将来的文件结尾位置。 在所有情况下,该节都可能会扩展到当前文件末尾。

在Linux上, lockf()只是fcntl(2)锁定之上的接口。 许多其他系统也以这种方式实现lockf() ,但请注意,POSIX.1 lockf()指定lockf()fcntl(2)锁之间的关系。 便携式应用程序可能应该避免混合使用这些接口。

有效操作如下:

  • F_LOCK在文件的指定部分设置排他锁。 如果此部分(的一部分)已被锁定,则调用将阻塞,直到释放先前的锁定为止。 如果此部分与先前锁定的部分重叠,则两者将合并。 一旦持有锁的进程关闭文件的某些文件描述符,就会释放文件锁。 子进程不会继承这些锁。
  • F_TLOCKF_LOCK但呼叫从未块并返回,而不是如果该文件已被锁定的错误。
  • F_ULOCK解锁文件的指示部分。 这可能导致锁定部分被分成两个锁定部分。
  • F_TEST测试锁:如果指定的部分已被此过程解锁或锁定,则返回0;否则返回0。 返回-1 ,如果另一个进程持有锁,则将errnoEAGAIN (在某些其他系统上为EACCES )。

但这仅是排他锁,因此并不真正适用于单写,多读的情况。

我看一下unix套接字( man unix )。 它们就像文件或套接字(它们是套接字,但是您可以在它们上使用file-io函数)一样工作,并尝试关联其他人已经拥有的套接字(可以像普通文件一样驻留在文件系统中)失败。

老实说,您尝试做的事情听起来很像IPC(进程间通信),这很好–但是您可能希望了解简单共享内存的协调! shmget和类似的东西将使您能够以类似于文件的方式打开事物,并且您可以以这种方式直接在进程之间以高性能直接交换数据,而不会造成将数据写入磁盘的麻烦。 (您可以非常相似地将实际文件映射到内存中,但是不能解决锁定问题)。

但是:这些是解决IPC问题的非常底层的方法。 我建议实际使用IPC库。 有很多产品可以满足不同系统的需求-从大型集群类系统的MPI,非常好的基于套接字的系统或类似套接字的灵活系统(想到了ZeroMQ)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM