linux下多進程同時操作文件


轉自:https://blog.csdn.net/u011508527/article/details/46878205

我們都知道多進程同時操作文件會出現問題,但是具體會出現什么問題呢?不知道大家有沒有仔細研究過,今天我就帶大家一起來研究一下。

在操作文件之前,很有必要了解一下內核中文件的存儲和訪問方式:

這張圖摘自《APUE》,我覺得畫的很好,所以就沒有自己再畫了。

從圖中能夠看出每個進程都有自己獨立的一個進程表項,由文件指針指向文件表項;在文件表項中兩個很重要的東西:狀態標志和當前文件偏移量,問什么說它很重要,因為在多進程寫文件出錯時,一般都是由文件偏移量引起的(這個后面會講到);然后由V節點指針指向一個V節點表(關於i節點我會在另外的博客中闡述)

第一種情況:父子進程同時寫一個文件

父進程再用fork函數創建子進程的時候,會把自己的上下文環境拷貝一份復制到子進程的內存空間中,這里當然包括進程表。所以子進程的進程表和父進程的是一模一樣的,它們指向的是同一個文件表,上面講到過,當前偏移量會引起文件操作錯誤。

對於這個文件偏移量,有幾點需要搞清楚:在用open函數打開文件時如果沒有加上O_APPEND標志,那么這個文件表的文件偏移量為0;加上的話,它會把V節點中的當前文件長度賦給文件偏移量;寫完文件之后(沒有關閉文件描述符),文件長度會變化,相應的當前偏移量也隨着文件長度的變化而變化。這里需要注意,是寫完一個文件之后(也就是write函數執行完之后),便宜量才會改變。

到這里的話,基本上就清楚了:如果寫操作是一個原子操作的話(可以用pwrite實現),那么父子進程寫同一個文件不會出現任何問題;如果不是原子操作的話,有可能在父進程的write函數沒有返回之前又執行了子進程的write函數,由於當前文件偏移量沒有改變,所以會覆蓋掉原先內容。

第二種情況:非父子進程寫同一個文件

對於非父子類型的多進程寫同一個文件,其情況又是另外一回事了:

進程各自有各自的進程表,至於為什么要有各自的進程表而不是共享一個進程表?可以這么想:各個進程打開文件的標志可能會不一樣,有的可能只讀、只寫、或者讀寫方式,這樣的話,它們中的內容肯定會不一樣。

對於fd0,假設它剛剛寫完一個文件,fd0指向的文件表中的當前偏移量改變了,但是fd1中的偏移量沒有改變,這就造成fd1在寫文件時會覆蓋fd0寫入文件的內容。

具體情況大家可以在自己的機器上試驗一下。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM