本節書摘來自異步社群《unix網絡程式設計 卷2:程序間通信(第2版)》一書中的第1章,第1.1節,作者:【美】w. richard stevens著,更多章節内容可以通路雲栖社群“異步社群”公衆号檢視
ipc是程序間通信(interprocess communication)的簡稱。傳統上該術語描述的是運作在某個作業系統之上的不同程序間各種消息傳遞(message passing)的方式。本書還講述多種形式的同步(synchronization),因為像共享記憶體區這樣的較新式的通信需要某種形式的同步參與運作。
在unix作業系統過去30年的演變史中,消息傳遞曆經了如下幾個發展階段。
管道(pipe,第4章)是第一個廣泛使用的ipc形式,既可在程式中使用,也可從shell中使用。管道的問題在于它們隻能在具有共同祖先(指父子程序關系)的程序間使用,不過該問題已随有名管道(named pipe)即fifo(第4章)的引入而解決了。
system v消息隊列(system v message queue,第6章)是在20世紀80年代早期加到system v核心中的。它們可用在同一主機上有親緣關系或無親緣關系的程序之間。盡管稱呼它們時仍冠以“system v”字首,當今多數版本的unix卻不論自己是否源自system v都支援它們。
在談論unix程序時,有親緣關系(related)的說法意味着所論及的程序具有某個共同的祖先。說得更明白點,這些有親緣關系的程序是從該祖先程序經過一次或多次fork派生來的。一個常見的例子是在某個程序調用fork兩次,派生出兩個子程序。我們說這兩個子程序是有親緣關系的。同樣,每個子程序與其父程序也是有親緣關系的。考慮到ipc,父程序可以在調用fork前建立某種形式的ipc(例如管道或消息隊列),因為它知道随後派生的兩個子程序将穿越fork繼承該ipc對象。我們随圖1-6詳細讨論各種ipc對象的繼承性。我們還得注意,從理論上說,所有unix程序與init程序都有親緣關系,它是在系統自舉時啟動所有初始化程序的祖先程序。然而從實踐上說,程序親緣關系開始于一個登入shell(稱為一個會話)以及由該shell派生的所有程序。apue的第9章詳細讨論會話和程序親緣關系。 本書将全文使用縮進的插入式注解(如此處所示)來說明實作上的細節、曆史上的觀點以及其他瑣事。
posix消息隊列(posix消息隊列,第5章)是由posix實時标準(1003.1b-1993,将在1.7節詳細讨論)加入的。它們可用在同一主機上有親緣關系和無親緣關系的程序之間。
遠端過程調用(remote procedure call,簡稱rpc,第5部分)出現在20世紀80年代中期,它是從一個系統(客戶主機)上某個程式調用另一個系統(伺服器主機)上某個函數的一種方法,是作為顯式網絡程式設計的一種替換方法開發的。既然客戶和伺服器之間通常傳遞一些資訊(被調用函數的參數與傳回值),而且rpc可用在同一主機上的客戶和伺服器之間,是以可認為rpc是另一種形式的消息傳遞。
看一看由unix提供的各種同步形式的演變同樣頗有教益。
需要某種同步形式(往往是為了防止多個程序同時修改同一檔案)的早期程式使用了檔案系統的詭秘特性,我們将在9.8節讨論其中的一些。
記錄上鎖(record locking,第9章)是在20世紀80年代早期加到unix核心中的,然後在1988年由posix.1标準化的。
system v信号量(system v semaphore,第11章)是在system v消息隊列加入system v核心的同時(20世紀80年代早期)伴随system v共享記憶體區(system v shared memory)加入的。當今多數版本的unix都支援它們。
posix信号量(posix semaphore,第10章)和posix共享記憶體區(posix shared memory,第13章)也由posix實時标準(1003.1b-1993)加入。
互斥鎖(mutex)和條件變量(condition variable,見第7章)是由posix線程标準(-1995)定義的兩種同步形式。盡管往往用于線程間的同步,它們也能提供不同程序間的同步。
讀寫鎖(read-write lock,第8章)是另一種形式的同步。它們還沒有被posix标準化,不過也許不久後會被标準化。