linux操作系統-3進程管理(3)

LINUX下進程間通信IPC

在LINUX內核中,進程各自的用戶地址空間是相互獨立的。支持POSIX規範中標準的IPC。

1、管道

使用簡單,侷限性:半雙工,即一條管道中數據只能單一方向流動。

管道兩端的進程必須是父子關係或具有相同的祖先

使用模式:進程通過系統調用pipe(int fd[2])創建一條管道,返回0代表系統調用成功。fd[0]賦值爲管道讀端,fd[1]賦值爲管道寫端。進程調用fork()系統調用創建一個新的子進程。

在linux內核中,管道是藉助於管道文件系統(pipefs)來實現的。在文件系統的inode結構中,有一個指向struct pipe_inode_info類型的指針i_pipe,這樣就把文件系統與管道聯繫起來。

2、命名管道

FIFO,是一種特殊的文件(類型爲S_IFIFO)在文件系統中真實存在。兩個或多個進程可以同時打開並讀寫FIFO文件以達到進程通信的目的。進程操作FIFO文件方法與操作普通文件的方法完全相同。是一種雙向的進程間通信機制。

實現與管道的類似處是,都是通過pipefs文件系統來完成的,不同之處是管道是通過Pipe系統調用創建的,所以當管道的文件描述符關閉或相關的進程退出後管道就不存在了;而FIFO是通過mknod系統調用創建的,因而在虛擬文件系統中真實存在一個FIFO文件。所謂命名管道就是利用文件系統(FIFO文件的Inode)建立起與管道緩衝區的映射,避免管道對於父子進程或相關進程的限制。

3、消息隊列

管道和FIFO侷限性是僅僅提供了基本的通信方法,用戶如果真正使用它們傳送消息,還需要自己定義消息的格式、大小並保證消息的完整性。另外,只能順序讀寫。最後管道要求通信的雙方都要同時連接在管道的兩端(否則會接到SIGPIPE錯誤信號)。

消息隊列可以看成是消息的鏈表,用來提供進程間簡短信息的傳遞。

LINUX內核實現了系統五和POSIX規範兩種形式的消息隊列。

1)sys V

消息隊列在內核中創建了消息的鏈表,每個消息隊列有一個唯一的隊列標示msgid,應用程序可以使用msgget系統調用來打開或創建一個消息隊列並得到相應的標識。消息隊列提供的一個重要特徵就是消息的分類。在發送和接收消息的時候都可以指定消息類型。系統五消息隊列消息的分類機制是在接收端實現的。

2)POSIX

與系統五相比,增加:

簡化了基於文件的接口;

增強的消息優先級支持;

異步消息機制,並可指定通過信號處理函數或創建新的進程來處理消息;

可設置超時的可阻塞的消息發送和接收方法。

mq_open()打開隊列,mq_send(),mq_receive(),mq_close()

LINUX內核通過mqueue文件系統實現POSIX消息隊列。藉助虛擬文件系統。

4、共享內存

同一塊物理內存分別映射到不同進程的虛擬地址空間來實現數據的交換。由於數據不需要在進程和進程之間複製,因此在理論上這是一種最快速的IPC機制。

shmget系統調用創建一個新的或者取得一個已經建立的共享內存標識shmid,使用shmat系統調用把由shmid標識的共享內存片段映射到調用進程的虛擬地址空間中,接下來就可以像操作普通虛擬內存那樣操作這塊共享內存進程操作。最後使用完畢後還要調用shmat系統調用釋放共享內存的映射。若需要釋放共享內存本身,shmctl系統調用(加命令選項IPC_RMID)來完成。

共享內存是通過shm文件系統實現的。

共享內存雖然具有使用簡單、傳輸速度快等優點,但對於給定存儲空間的內容卻沒有任何保護(由於共享內存的訪問與普通內存操作相同),信號量作爲一種常見的同步機制被用來完成對共享內存讀寫的保護

(轉載)1.信號量的定義:

信號量(Semaphore),有時被稱爲信號燈,是在多線程環境下使用的一種設施, 它負責協調各個線程, 以保證它們能夠正確、合理的使用公共資源。

Semaphore分爲單值和多值兩種前者只能被一個線程獲得,後者可以被若干個線程獲得

以一個停車場的運作爲例。簡單起見,假設停車場只有三個車位,一開始三個車位都是空的。這時如果同時來了五輛車,看門人允許其中三輛直接進入,然後放下車攔,剩下的車則必須在入口等待,此後來的車也都不得不在入口處等待。這時,有一輛車離開停車場,看門人得知後,打開車攔,放入外面的一輛進去,如果又離開兩輛,則又可以放入兩輛,如此往復。

在這個停車場系統中,車位是公共資源,每輛車好比一個線程,看門人起的就是信號量的作用。

抽象的來講,信號量的特性如下:信號量是一個非負整數(車位數),所有通過它的線程/進程(車輛)都會將該整數減一(通過它當然是爲了使用資源),當該整數值爲零時,所有試圖通過它的線程都將處於等待狀態。在信號量上我們定義兩種操作: Wait(等待) 和 Release(釋放)。當一個線程調用Wait操作時,它要麼得到資源然後將信號量減一,要麼一直等下去(指放入阻塞隊列),直到信號量大於等於一時。Release(釋放)實際上是在信號量上執行加操作,對應於車輛離開停車場,該操作之所以叫做“釋放”是因爲釋放了由信號量守護的資源。

信號量,是可以用來保證兩個或多個關鍵代碼段不被併發調用。在進入一個關鍵代碼段之前,線程必須獲取一個信號量;一旦該關鍵代碼段完成了,那麼該線程必須釋放信號量。其它想進入該關鍵代碼段的線程必須等待直到第一個線程釋放信號量。爲了完成這個過程,需要創建一個信號量VI,然後將Acquire Semaphore VI以及Release Semaphore VI分別放置在每個關鍵代碼段的首末端。確認這些信號量VI引用的是初始創建的信號量。


5、套接口

socket不但支持在同一臺主機上的進程間通信,還支持不同主機上的進程間通信。根據使用域可以分爲網絡套接口UNIX域套接口。前者可用於不同主機上的進程間通信,而後者只能用於同一主機上的進程間通信。


發佈了27 篇原創文章 · 獲贊 13 · 訪問量 8萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章