簡體   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