大陸論壇上找到的分享之

Problem:


目的:試圖open一個文件,若文件不存在就建立它。
open(pathname, O_RDWR | O_CREAT,0666);就不行吗?为什麼好多資料上說要加O_EXCL,說是唯一單體的運動方式,不加難道就不是了嗎?不解

說的是,但目的是“試圖open一个文件,若檔案不存在就建立它。”再加這一句讓它返回一个錯誤有什麼用呢?如果檔案存在反而不能打開這個檔案,如果要測試檔案是否存在我只要一個O_EXCL不就行了。很多資料上都是O_CREAT | O_EXCL, 我實在不知道這樣做的用途何在?

Answer


哦,我還以為弄清楚了呢,結束帖子了。

設想這樣一個需求:某個任務要求只能單個進程執行,不能多個進程同時執行。
但是不能確保多個進程同時啟動,嘗試執行這個任務。

这样就进一步要求,只有第一个执行的进程可以继续,后续尝试执行的进程都报错退出。

方案之一就是使用带有O_EXCL标志的open()尝试打开一个文件。
第一个进程执行时文件并不存在,它能成功创建文件并继续执行。
第二个及后续的其它进程会因为文件已存在,从而open()失败,进程退出。

如果不使用O_EXCL标志,那你的代码可能要这样写:
if( access(file, R_OK) == -1 ) /* 首先检查文件是否存在 */
open(file, O_RDWR | O_CREAT,0666); /* 如果不存在,那我创建一个这样的文件 */
... /* 继续执行任务 */

這個邏輯是有潜在的問题的,那就是判断檔案是否存在與建立檔案是兩個獨立的系统呼叫。
如果进程1执行access,判断出文件并不存在;
然後由於操作系统的调度策略,進程1暂停執行,進程2執行,進程2也會判断出檔案不存在。

最终结果就是:兩個進程呼叫open時都會成功,然後繼續執行。這樣就有多個進程同時執行這個任務了。

哦,說了這麼一堆啊~~


以下是man page(男人)的說明

O_EXCL If O_CREAT and O_EXCL are set, open() shall fail if the file exists. The check for the existence of the file and the creation of the file if it does not exist shall be atomic with respect to other threads executing open() naming the same filename in the same directory with O_EXCL and O_CREAT set. If O_EXCL and O_CREAT are set, and path names a symbolic link, open() shall fail and set errno to [EEXIST], regardless of the contents of the symbolic link. If O_EXCL is set and O_CREAT is not set, the result is undefined.

arrow
arrow
    全站熱搜

    ryan0988 發表在 痞客邦 留言(0) 人氣()