當多個進程「同時」對同一個文件進行讀寫操作時,Linux 內核究竟如何協調?本文通過三個進程(A 讀前 100 字符、B 讀含「aa」行、C 寫入「ABC」)的啟動順序與實際執行順序對比,詳細闡述文件表、inode、緩衝區鎖、等待隊列、中斷喚醒等核心機制的交互過程,還原內核視角下的真實並發處理邏輯。
file_table[64] 中建立指針關聯到文件的 inode,賦予操作權限。A 首先建立文件表關聯,發起讀取請求。內核分配空閒緩衝區、發起磁盤 I/O、對緩衝區加鎖。因 I/O 未完成,A 進入 TASK_UNINTERRUPTIBLE 狀態,掛入緩衝區等待隊列隊首。
B 同樣建立文件表關聯(inode 已緩存,無需再遍歷)。讀取時通過哈希表發現目標緩衝區已在載入中,引用計數增為 2。B 同樣掛起,插入隊列 A 之後。
C 建立關聯後發起寫入,同樣等待緩衝區解鎖。因最後到達,插入隊列最前端(實現細節取決於具體內核版本隊列插入策略,本文假設新到者插隊首)。
關鍵結論:雖然啟動順序為 A→B→C,但**實際執行順序為 C→B→A**,完全由等待隊列順序決定。
三個進程退出後,數據修改仍駐留在頁緩存,並未立即落盤。內核 update/flush 線程(或 pdflush、writeback)會定期將髒頁同步至磁盤,保證最終一致性。此過程涉及 fsync、sync_file_range 等系統調用可強制落盤。
理解上述機制,有助於在高併發存儲場景中設計正確的鎖策略、選擇適當 I/O 模型(如 O_DIRECT、mmap、異步 I/O)並排查性能瓶頸。