前言
假如要你寫一段程式碼建立一個檔案( 如果檔案已經存在則返回失敗 )。你會怎麼做?
本文將討論兩種做法,並進行分析。
錯誤程式碼示例
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 }
說明
在系統程式設計中,我們要多多考慮併發可能給程式帶來的影響。