5123 Readuq和寫入管道

應該將管道視為流程,就像過程寫入管道的一端並從另一端讀取一樣。如上所述,以FIFO方式從管道中訪問數據,這意味著將數據寫入管道的順序是從管道中讀取的順序。從管道中讀取的過程數量不一定等於編寫管道的過程數量。如果讀者或作家的數量大於1,則必須將管道使用與其他機製進行協調。當訪問一個數據時,內核可以訪問管道的數據常規文件:它將數據存儲在管道設備上,並根據需要在打電話期間根據需要將塊分配給管道。管道的存儲分配之間的差異和

圖5.17。閱讀和寫管道的邏輯觀點

一個常規文件是,管道僅使用inode的直接塊以提高效率,盡管這限製了管道一次可以容納多少數據。內核將inode的直接塊作為圓形隊列操縱,並在內部保持讀寫指針以保留FIFO順序(圖5.17)。

考慮四個用於閱讀和寫入管道的情況:WRT環有一個有空間編寫數據的管道,從管道中讀取的管道包含足夠的數據來滿足讀取,從管道中讀取的管道不含足夠的數據來滿足讀取,最後,wr/'響了一個沒有空間編寫數據的管道。

首先考慮一個過程正在編寫管道,並假設管道有編寫數據的空間:編寫字節的數量和管道中的字節數小於或等於管道的。容量。內核遵循編寫常規文件的算法,隻是每次寫入後它會自動遞增管道大小,因為根據定義,管道中的數據量隨著每個寫入而生長。這與常規文件的增長不同,該文件僅在文件大小上列出數據以外的文件端以外時會增加文件大小。如果下一個字節偏移在管道中需要使用間接塊,內核調整U區域中的文件偏移值,以指向管道的開始(字節偏移0)。內核永遠不會覆蓋管道中的數據;它可以將字節偏移重置為0,因為它已經確定數據不會溢出管道的容量。當作者進程將所有數據寫入管道中時,內核會更新管道(Inode)寫入指針,以便下一個寫管道的過程將從上一篇寫入停止的位置進行。然後,內核喚醒了所有其他入睡的過程,等待從管道中讀取數據。

當過程讀取管道時,它會檢查管道是否為空。如果管道包含數據,則內核會按照常規算法進行讀取,將管道讀取管道的數據,好像管道是常規文件一樣。但是,它的初始偏移是存儲在Inode中的管道讀取指針,表明上一讀的程度。閱讀每個塊後,內核根據讀取的字節數減小管道的大小,並在必要時調整U麵積偏移值以將其包裹到管道的開頭。當讀取係統呼叫完成後,內核喚醒了所有睡眠作家的過程,並保存當前讀取偏移量(而不是在文件表入口)。

如果一個過程試圖讀取比管道中更多的數據,則讀取將在返回管道中當前的所有數據後成功完成,即使它不滿足用戶數量。如果管道為空,則該過程通常會睡覺,直到另一個過程將數據寫入管道為止,此時所有等待數據喚醒並競爭讀取管道的睡眠過程。但是,如果一個過程打開一個沒有延遲選項的命名管道,則如果管道不包含數據,它將立即從讀取中返回。閱讀和寫入管道的語義類似於閱讀和寫作終端設備的語義(第10章),允許程序忽略他們正在處理的文件類型。

如果一個過程寫入管道,並且管道無法容納所有數據,則內核標記了inode並進入睡眠,等待數據從管道上排出。當另一個過程隨後從管道中讀取時,內核會注意到過程正在睡覺,等待數據從管道上排出,並且它將喚醒它們,如上所述。該語句的例外是一個過程寫入大於管道容量的數據量(即可以存儲在Inode Direct Blocks中的數據量);在這裏,內核將盡可能多的數據寫入管道,並將過程放在睡眠狀態,直到有更多空間可用。因此,如果其他過程在此過程恢複其寫入之前,其他過程將其數據寫入管道,則可能在管道中不連續。

分析管道的實現,該過程接口與常規文件的接口一致,但是實現之所以有所不同,是因為內核將讀取和注銷偏移存儲在Inode中而不是在文件表中。內核必須將偏移存儲在命名管的inode中,以便過程可以共享其值:由於一個過程獲取每個打開調用的新文件表條目,因此它們無法共享存儲在文件表條目中的值。但是,Inode中讀取和注銷偏移的共享早於命名管的實現。通過通用文件表條目共享對未命名管的訪問權限的過程,因此可以想象它們可以像常規文件一樣將讀取和注銷偏移存儲在文件表條目中。這不是這樣做的,因為內核中的低級例程不再可以訪問文件表條目:代碼更簡單,因為該過程共享存儲在Inode中的偏移。

SL12.4關閉管道

關閉管道時,一個過程遵循相同的過程,將關閉常規文件的過程將遵循,除了內核在釋放管道的Inode之前進行特殊處理。根據文件描述符的類型,內核減少了管道讀取器或作家的數量。如果作者的計數下降到

0,還有一些進程入睡,等待從管道中讀取數據,內核喚醒了它們,如果讀者的計數下降到0,則它們從閱讀的呼叫中返回而無需閱讀任何數據,並且有進程入睡,等待將數據寫入到該數據管道,內核喚醒它們,並向他們發送信號(第7章),以指示錯誤條件。在這兩種情況下,在沒有希望狀態會改變的情況下,允許過程繼續睡覺毫無意義。例如,如果一個過程正在等待閱讀未命名的管道,並且沒有更多的作者流程,那麼將永遠不會有作者流程。盡管有可能獲得命名管道的新讀者或作家流程,但內核可以用未命名的管道始終如一地對待它們。如果沒有讀者或作者處理管道,則內核會釋放其所有數據塊,並調整Inode以表明管道是空的。當它釋放普通管道的inode時,它會釋放磁盤副本進行重新分配。

Maino

繼續在這裏閱讀:61過程狀態和過渡

本文是否有幫助?

0 0

讀者的問題

  • Kaarle Hongisto
    Unix中的管道是什麼?
    3天前
  • UNIX中的管道是將一個命令的標準輸出重定向到另一個命令的標準輸入的過程。管道允許用戶將一個命令的輸出重定向到另一個命令的輸入,而無需在兩個命令之間創建文件。這可以使用垂直杆操作員(|)完成。