當前位置:
首頁 >
O_EXCL
發(fā)布時間:2023/12/10
43
豆豆
open系統(tǒng)調(diào)用:
#include <fcntl.h>int open(const char *pathname, int oflag, ... /*mode_t mode */ );其中,oflag有個可選值為:
O_EXCL
Generate an error if?O_CREAT?is also specified and the file already exists.?
This test for whether the file already exists and the creation of the file if it doesn't exist is an atomic operation.?
We describe atomic operations in more detail in Section 3.11.
譯文:當 O_CREAT 與 O_EXCL 同時使用,并且如果要打開的文件已經(jīng)存在,那么該調(diào)用就返回error,表明打開不成功。因此,我們可以使用該方法(即 O_CREAT 與 O_EXCL 同時使用)來實現(xiàn)以下三步的原子性操作:1 檢查某個文件是否存在2 如果文件不存在,就創(chuàng)建該文件,返回 success3 如果文件已經(jīng)存在,就返回error,通知調(diào)用者文件已經(jīng)存在---------------------------------------------華麗麗的分割線-----------------------------------以下是從網(wǎng)上找的一些信息:$ man open......
? O_EXCL Ensure that this call creates the file: if this flag is specified in conjunc-
? tion with O_CREAT, and pathname already exists, then open() will fail.?The
behavior of O_EXCL is undefined if O_CREAT is not specified.=============================================================================================設(shè)想這樣一個需求:某個任務(wù)要求只能單個進程執(zhí)行,不能多個進程同時執(zhí)行。
但是不能確保多個進程同時啟動,嘗試執(zhí)行這個任務(wù)。
這樣就進一步要求,只有第一個執(zhí)行的進程可以繼續(xù),后續(xù)嘗試執(zhí)行的進程都報錯退出。
方案之一就是使用帶有O_EXCL標志的open()嘗試打開一個文件。
第一個進程執(zhí)行時文件并不存在,它能成功創(chuàng)建文件并繼續(xù)執(zhí)行。
第二個及后續(xù)的其它進程會因為文件已存在,從而open()失敗,進程退出。
如果不使用O_EXCL標志,那你的代碼可能要這樣寫:
if( access(file, R_OK) == -1 ) /* 首先檢查文件是否存在 */
? open(file, O_RDWR | O_CREAT,0666); /* 如果不存在,那我創(chuàng)建一個這樣的文件 */
... /* 繼續(xù)執(zhí)行任務(wù) */
這個邏輯是有潛在的問題的,那就是判斷文件是否存在與創(chuàng)建文件是兩個獨立的系統(tǒng)調(diào)用。
如果進程1執(zhí)行access,判斷出文件并不存在;
然后由于操作系統(tǒng)的調(diào)度策略,進程1暫停執(zhí)行,進程2執(zhí)行,進程2也會判斷出文件不存在。
最終結(jié)果就是:兩個進程調(diào)用open時都會成功,然后繼續(xù)執(zhí)行。這樣就有多個進程同時執(zhí)行這個任務(wù)了。---------------------------------------------------------------------------------------------------總結(jié)下 (O_EXCL|O_CREAT)與 O_CREAT 的區(qū)別:1 單獨使用 O_CREAT 時,無論文件在該調(diào)用執(zhí)行時,是否存在,都會成功返回(不考慮所在目錄權(quán)限、文件權(quán)限的問題)。如果應(yīng)用程序只要求確保文件在后續(xù)程序執(zhí)行時,該文件已經(jīng)存在,則單獨使用 O_CREAT 就可滿足該應(yīng)用要求。但有一個不足之處就是:當open成功返回后,我們需要知道該文件是之前已經(jīng)存在呢,還是之前不存在而剛剛創(chuàng)建出來的。如果有這種需求,那么 單獨使用 O_CREAT 就不能搞定了。此時,就需要使用(O_EXCL|O_CREAT)。2 當使用(O_EXCL|O_CREAT)時,若文件已存在,則返回錯誤;過不存在,則返回成功。但返回不論成功、錯誤,返回后,文件肯定已經(jīng)存在了。因此,該方式能夠給程序員提供更多的信息量。
區(qū)別應(yīng)該就在這里吧。
那么在apue中,在介紹?Ensure that only one copy of a daemon is running中,作者并沒有使用(O_EXCL|O_CREAT)來通過判斷某個文件是否存在來判斷是否有某個進程的其它實例正在運行。而是采用了O_CREAT,而后加“寫鎖”的方式。
想想這兩種方式的特點:
如果采用?(O_EXCL|O_CREAT)來實現(xiàn)單實例進程,那么進程結(jié)束之前,必須要先刪除鎖文件,否則,以后該程序就無法運行了。因此問題就在如何保證刪除鎖文件。比如突然斷電,程序還沒來得及刪除鎖文件,那么下次再無法運行了。處理好這個問題需要額外畫一些功夫。
apue中采用的采用 record lock 的方式,應(yīng)該是不存在上面提到的這種問題。
總結(jié)
- 上一篇: SIP应答消息状态码与功能
- 下一篇: WinCE6.0的EBOOT概要