操作系統基礎原理(五)

線程通信

線程對白:管道,記名管道,套接字
線程對白就是一個線程發出來的某種數據信息,另外一方接收數據信息,這些數據通過一片共享的存儲空間進行傳遞。

管道

一個線程向存儲空間一端寫入信息,另一個線程從存儲空間的另一端讀取信息,這就是管道,管道既可以是內存就也可以是磁盤,要創建一個管道,一個線程只需要調用管道創建的系統調用即可。
管道是一個線性字節數組,類似文件,使用文件讀寫的方式進行訪問,但卻又不是文件,因爲通過文件系統看不到管道的存在,創建管道在殼命令行下和在程序是不同的,在殼命令下,只需要使用符號"|"即可。
UNIX下創建管道

$ sort < file1 | grep zou

在兩個utility"sort"和"grep"之間創建了一個管道
在程序下創建管道
創建管道需要使用系統調用popen()或者pipe()。popen需要提供一個目標進程作爲參數,然後在調用該函數的進程和給出的目標進程之間創建一個管道。
創建時還需要提供一個參數表明管道類型:讀管道或者寫管道,而pipe調用將返回兩個文件描述符,其中一個用於從管道進行讀寫,一用於寫管道。也就是說,pipe將兩個文件描述符連接起來,使得一端讀,另一端可以寫。通常情況下,在使用pipe調用創建管道後,再使用fork產生兩個進程,這兩個進程使用pipe返回的兩個文件描述符進行通信。
例子:

int pp[2];
pipe(pp);//創建管道
if(fork()==0)//子進程
{
read(pp[0]);//從父進程讀
............
}
else
{
write(pp[1]);//寫給子進程
.............;
}

管道的另外一個重要特點是使用管道的兩個線程之間必須存在某種關係。例如,使用popen需要提供另一端進程的文件名,使用pipe的兩個線程則分別隸屬於父子進程。

記名管道

如果要在兩個不相關的線程間進行通信,比如不同進程的線程,則需要使用記名管道。記名管道與文件系統共享一個名字空間,及我們可以從文件系統中看到記名管道,也就是說,記名管道的名字不能與文件系統裏的任何文件重名。
例如:
在UNIX下使用ls命令可以查看到已經創立的記名管道。

% ls-l fifol
prw-r--r-- 1 jhon user 0  Sep 22 23:11 fifol |

一個線程通過創建一個記名管道後,另外一個線程可以使用open來打開這個管道(無名管道不能進行open操作),從而與另一端進行交流。
記名管道名稱組成:由計算機名和管道名組成,例如:\[主機名]\管道[管道名]\。

優缺點
管道與記名管道無需特殊設計(指應用程序方面)就可以與另外一個進程進行通訊,但是不是所有操作系統都支持此功能,現在支持管道通信方式的是UNIX和類UNIX的操作系統。不適用於其他操作系統,其次,管道通信需要在相關的進程間進行(無名管道),或者需要直到名字來打開(記名管道),會顯得十分不便。

蟲洞:套接字

套接字是另一種可以用於進程間通信的機制。他幾乎滲透到所有主流操作系統,可支持不同層面,不同應用,跨網絡的通信。
大致流程:
通信雙方都需要創建一個套接字,其中一方作爲服務器方,另一方作爲客戶方,服務器方必須先創建一個服務區套接字,然後在該套接字上監聽,等待遠方的連接請求。想要與服務器方通信的客戶自創建一個客戶套接字,然後向服務區套接字發送連接請求。服務器套接字在收到連接請求後,將服務器上創建一個客戶套接字,與遠方的客戶機上的客戶套接字形成點對點的通信信道。之後客戶端和服務器端就可以通過send和recv命令在這個創建的套接字上進行交流了。
綁定
服務器想要提供網頁瀏覽服務需要綁定,服務器套接字可以綁定道某個公共主機的一個衆所周知的端口,當然,如果綁定道某個具體的IP地址,則只能在本地機器上使用!
注意
服務器套接字不發送數據,也不接收數據(用戶數據,而非連接請求數據),而是僅僅生成出“客戶”套接字,生成後,原本的服務套接字則回到原來的監聽操作上。

線程電報:信號

管道和套接字的效率十分低下,且耗資源。而信號就是我們要講的下一個通信機制。
**是什麼:**在計算機裏,是一個內核對象,或者說是一個內核數據結構。發送方將數據結構的內容填好,並指明該信號的目標進程後,發出特定的軟件中斷通知操作系統,操作系統知道是有進程要發送信號,於是到特定的內核數據結構裏查找信號接收方,並進行通知,接收到通知的進程對信號進行相應處理。

線程旗語:信號量

在計算機裏,信號量就是一個簡單的整數,一個進程在信號變爲0或者1的情況下推進,並且將信號變爲1或者0來防止別的進程推進。
信號量不光是一種通信機制,更是一種同步機制。

線程擁抱:內存共享

一個進程首先創建一片內存空間專門作爲通信用,而其他進程則將該內存空間映射到自己的虛擬地址空間,這樣讀寫自己地址空間中對應共享內存的區域時,就是在和其他進程通信(隨機)。
優缺點
靈活度高,傳遞信息也複雜得多,但是兩個進程必須在同一臺物理機器上才能使用,且安全性較低。
在這裏插入圖片描述
注意:使用全局變量在同一個進程的線程間實現通信不稱爲共享內存你。

信件發送:消息隊列(只在內存中應用)

一列具有頭和尾的消息排列。新的消息放在尾部,而讀取消息則從隊列頭部開始:
在這裏插入圖片描述
它類似管道,但是它無需固定的讀寫線程,任何進程都可以讀寫,也可以同時支持多進程,多個進程可以讀寫消息隊列。即多對多,不是管道的點對點。流行於幾乎所有主流操作系統。

其他通信機制

通信機制繁多,但是原理卻並無太大差異。歸根結底都來源於AT&T的UNIX V系統。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章