2017-08-19 119 views
0

問題:在Linux平臺上創建新文件或覆蓋現有文件,以便其他進程可以打開它以便只讀。使用CreateFile一個可以做這樣的事情:Linux文件鎖定

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

此調用會失敗,如果它是用相似的標識另一個進程打開,覆蓋現有文件。

如何在Linux上實現類似的行爲?假定諮詢鎖受到所有程序的尊重。

+0

您使用了[tag:C++]和[tag:c]標籤,但代碼只能是C++ **或** C.不能。你沒有提出一個問題,你只是說了一個問題,所以...這是令人遺憾的不清楚。你**必須提出一個明確的問題,在問題的最後帶一個問號,以便我們能夠清楚地回答它。 –

+0

這是一個有點問題的問題 - 你需要添加*更多*細節你打算做什麼。在Linux中沒有正確的*強制*文件鎖定 - 鎖只是建議性的 - 即一個糟糕的程序可以忽略它們 - 這些適合你嗎? –

+0

@MarcusMüller其實,這裏的語言不太相關 - 與Linux系統調用語義更相關。 –

回答

0

使用open和建議flock鎖定,作家需要持有LOCK_EX排他鎖。讀者一定不能持有任何鎖,他們然後可能會看到文件突然截斷。

Plain 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鎖定文件,否則它不能通過令狀打開呃。

0

您正在尋找的flocklockf功能:)

這其中大部分是非常基礎上man 2 flockman lockf,所以我非常樂意推薦閱讀它。

這是從man lockf

#include <unistd.h> 

int lockf(int fd, int cmd, off_t len); 

...

說明

應用,測試或在一個開放的文件的部分刪除一個POSIX鎖。該文件由fd指定,一個文件描述符打開爲 寫入,由cmd執行,該部分由 字節位置pos..pos + len-1(如果len爲正數)和pos-len..pos-1如果len是負數,其中pos是當前文件的 位置,並且如果len爲零,則該部分從 當前文件位置延伸到無窮大,包含當前和未來的文件結束位置。在所有情況下,該部分可以在當前文件結束之後延伸 。

在Linux上,lockf()只是fcntl(2)鎖定的接口。許多其他系統以這種方式實現lockf(), ,但是請注意,POSIX.1保留了未指定的鎖之間的關係 lockf()fcntl(2)。一個便攜式應用程序可能應該避免混合調用這些接口。

有效的操作如下:

  • F_LOCK對文件設置的指定部分的獨佔鎖。如果此部分(的一部分)已被鎖定,則會阻止呼叫,直到釋放上一個鎖。如果此部分與先前鎖定的部分重疊,則兩者都合併。只要持有鎖的進程關閉文件的某個文件描述符,文件鎖就會被釋放。子進程不會繼承這些鎖。
  • F_TLOCKF_LOCK相同,但是如果文件已被鎖定,則調用不會阻止並返回錯誤。
  • F_ULOCK解鎖文件的指定部分。這可能會導致鎖定部分被分成兩個鎖定部分。
  • F_TEST測試鎖定:如果指定部分被此進程解鎖或鎖定,則返回0;如果另一個進程持有鎖,則返回-1,將errno設置爲EAGAINEACCES)。

但是,這只是一個排它鎖,SOOO真的不適合單個作家,多讀者的情況。

我想看看unix套接字(man unix)。它們像文件或類似套接字一樣工作(它們是套接字,但是你可以在它們上使用file-io函數),並試圖將一個其他人已經擁有的套接字(它可以像普通文件一樣駐留在文件系統中)失敗。

說實話,你試圖做的聽起來很像IPC(進程間通信),這很好 - 但你可能想看看simlper共享內存的協調!和類似的東西可以讓你以非常類似文件的方式打開東西,並且可以以高性能直接在進程間交換數據,而不會招致將數據寫入磁盤的代價。 (可以非常類似地將實際文件緩存到內存中,但這並不能解決鎖定問題)。

但是:這些都是對IPC問題的非常低級的方法。我建議實際使用IPC庫。有很多適合不同系統需求的產品 - 從用於大型羣集系統的MPI,基於非常好的基於套接字的系統或類似套接字的靈活系統(想起zeroMQ)。