第六篇:一個開啟並建立檔案操作引發的討論

穆晨發表於2017-01-28

前言

       假如要你寫一段程式碼建立一個檔案( 如果檔案已經存在則返回失敗 )。你會怎麼做?

       本文將討論兩種做法,並進行分析。

錯誤程式碼示例

1 if ((fd = open(pathname, O_WRONLY)) < 0) {
2     if (errno == ENOENT) {
3         if ((fd = creat(pathname, mode)) < 0)
4             err_sys("creat error");
5     } 
6     else {
7         err_sys("open error");
8     }
9 }

錯誤分析

       這段程式碼錯在沒有考慮到作業系統中的程式併發。設想,如果有另一個程式在open和creat函式之間也creat了這個檔案,那麼當本段程式碼執行到第三行,就會有兩個程式同時對檔案進行處理,必然導致混亂。

解決辦法

       我們可以將open和creat函式之間的處理設為一個原子操作,即這段程式碼要麼不執行,一旦執行就必須執行完。

       open函式帶上 O_CREAT | O_EXCL 引數後,能以原子操作的方式實現這個功能。

正確程式碼示例

1 if ((fd = open(pathname, O_CREAT|O_EXCL)) < 0) { 
2     err_sys("open error");
3 }

說明

  在系統程式設計中,我們要多多考慮併發可能給程式帶來的影響。

相關文章