本機 IPC 對比網路 IPC(local vs network IPC)
兩個需要交談的行程,可能並肩坐在同一台電腦上,也可能相隔重洋、在不同機器上。它們的機制看起來相似得有點騙人——兩者都能用通訊端——但底下的現實截然不同,把兩者搞混是錯誤與糟糕設計的常見來源。本條目劃出界線,好讓你知道自己身處哪個世界。
本機 IPC 留在一台機器、一個核心之內。管線、FIFO、共享記憶體、訊息佇列、信號與 Unix 網域通訊端全都住在這裡。它們的資料從不碰到網路:位元組透過核心記憶體複製,或者用共享記憶體時根本不複製。所以本機 IPC 快(微秒或更短)、可靠(途中沒有封包會遺失)、有序,而且能做只有同機器才行的把戲,像傳遞檔案描述符、讀取對端的憑證。參與者共享同一個時鐘、同一個檔案系統、同一個作業系統。相對地,網路 IPC 把位元組跨過一條線(或無線)在分離的機器之間傳送,穿過 IP 堆疊、網路卡、交換器與路由器。現在你要面對以毫秒計的延遲、可能遺失、延遲、重複或亂序的封包、沒有共享記憶體、位元組序可能不同的機器、以及一個可能不告而別的對端。
實務上的結論:當雙方都在同一主機上時選本機 IPC——它更簡單、快得多,而且共享記憶體或 Unix 網域通訊端勝過把 TCP 連線繞回自己。只在你真的必須跨機器時才動用網路 IPC,並接受它的代價:你必須把資料序列化成約定的線上格式、處理部分讀取與斷線、應付位元組序、並為失敗而設計。誘人的陷阱在於 Unix 網域通訊端和 TCP 通訊端用的 API 幾乎一樣,這讓人容易忘記前者從不出大樓、後者卻要勇闖開放的網際網路。跨機器網路是它自己的領域;本條目只是那塊寫著「本機 IPC 到此為止」的路標。
同一機器:socket(AF_UNIX, ...)——位元組於核心內複製,微秒級,無遺失,可傳 fd。 不同機器:socket(AF_INET, ...)——位元組跨越網路,毫秒級,封包可能遺失/亂序,必須處理位元組序與失敗。
幾乎相同的 API,兩個不同的世界:一個留在核心,另一個勇闖網路線。
別只因為通訊端 API 支援就動用網路。同一主機上的兩個行程應該用本機 IPC——Unix 網域通訊端或共享記憶體——它比 TCP 迴路更快更簡單,而且不會丟封包。