1、無名管道通信
創新互聯成立以來不斷整合自身及行業資源、不斷突破觀念以使企業策略得到完善和成熟,建立了一套“以技術為基點,以客戶需求中心、市場為導向”的快速反應體系。對公司的主營項目,如中高端企業網站企劃 / 設計、行業 / 企業門戶設計推廣、行業門戶平臺運營、app軟件開發公司、手機網站開發、微信網站制作、軟件開發、成都二樞服務器租用托管等實行標準化操作,讓客戶可以直觀的預知到從創新互聯可以獲得的服務效果。
無名管道(pipe):管道是一種半雙工的通信方式,數據只能單向流動,而且只能在具有親緣關系的進程間使用,進程的親緣關系通常是指父子進程關系。
2、高級管道通信
高級管道(popen):將另一個程序當做一個新的進程在當前程序進程中啟動,則它算是當前程序的子進程,這種方式我們稱為高級管道方式。
3、有名管道通信
有名管道(named pipe):有名管道也是半雙工的通信方式,但是它允許無親緣關系進程間的通信。
4、消息隊列通信
消息隊列(message
queue):消息隊列是由消息的鏈表,存放在內核中并由消息隊列標識符標識,消息隊列克服了信號傳遞信息少、管道只能承載無格式字節流以及緩沖區大小受限等缺點。
5、信號量通信
信號量(semophore):信號量是一個計數器,可以用來控制多個進程對共享資源的訪問,它常作為一種鎖機制,防止某進程正在訪問共享資源時,其他進程訪問該資源。因此,主要作為進程間以及同一進程內不同線程之間的同步手段。
6、信號
信號(sinal):信號是一種比較復雜的通信方式,用于通知接收進程某個事件已經發生。
7、共享內存通信
共享內存(shared
memory):共享內存就是映射一段能被其他進程所訪問的內存,這段共享內存由一個進程創建,但多個進程都可以訪問。共享內存是最快的IPC方式,它是針對其他進程間通信方式運行效率低而專門設計的。它往往與其他通信機制,如信號量,配合使用,來實現進程間的同步和通信。
8、套接字通信
套接字(socket):套接字也是一種進程間通信機制,與其他通信機制不同的是,它可用于不同機器間的進程通信。
linux環境下實現進程之間的通信主要有以下幾種方式:
# 管道( pipe ):管道是一種半雙工的通信方式,數據只能單向流動,而且只能在具有親緣關系的進程間使用。進程的親緣關系通常是指父子進程關系。
# 有名管道 (named pipe) : 有名管道也是半雙工的通信方式,但是它允許無親緣關系進程間的通信。
# 信號量( semophore ) : 信號量是一個計數器,可以用來控制多個進程對共享資源的訪問。它常作為一種鎖機制,防止某進程正在訪問共享資源時,其他進程也訪問該資源。因此,主要作為進程間以及同一進程內不同線程之間的同步手段。
# 消息隊列( message queue ) : 消息隊列是由消息的鏈表,存放在內核中并由消息隊列標識符標識。消息隊列克服了信號傳遞信息少、管道只能承載無格式字節流以及緩沖區大小受限等缺點。
# 信號 ( sinal ) : 信號是一種比較復雜的通信方式,用于通知接收進程某個事件已經發生。
#共享內存( shared memory):共享內存就是映射一段能被其他進程所訪問的內存,這段共享內存由一個進程創建,但多個進程都可以訪問。共享內存是最快的IPC方式,它是針對其他進程間通信方式運行效率低而專門設計的。它往往與其他通信機制,如信號量,配合使用,來實現進程間的同步和通信。
# 套接字( socket ) : 套解口也是一種進程間通信機制,與其他通信機制不同的是,它可用于不同及其間的進程通信。
管道的主要局限性正體現在它的特點上:
只支持單向數據流;
只能用于具有親緣關系的進程之間;
沒有名字;
管道的緩沖區是有限的(管道制存在于內存中,在管道創建時,為緩沖區分配一個頁面大小);
管道所傳送的是無格式字節流,這就要求管道的讀出方和寫入方必須事先約定好數據的格式,比如多少字節算作一個消息(或命令、或記錄)等等;
第一種:管道通信
兩個進程利用管道進行通信時,發送信息的進程稱為寫進程;接收信息的進程稱為讀進程。管道通信方式的中間介質就是文件,通常稱這種文件為管道文件,它就像管道一樣將一個寫進程和一個讀進程連接在一起,實現兩個進程之間的通信。寫進程通過寫入端往管道文件中寫入信息;讀進程通過讀出端從管道文件中讀取信息。兩個進程協調不斷地進行寫和讀,便會構成雙方通過管道傳遞信息的流水線。
第二種:消息緩沖通信
多個獨立的進程之間可以通過消息緩沖機制來相互通信。這種通信的實現是以消息緩沖區為中間介質,通信雙方的發送和接收操作均以消息為單位。在存儲器中,消息緩沖區被組織成隊列,通常稱之為消息隊列。消息隊列一旦創建后即可由多進程共享,發送消息的進程可以在任意時刻發送任意個消息到指定的消息隊列上,并檢查是否有接收進程在等待它所發送的消息。若有則喚醒它,而接收消息的進程可以在需要消息的時候到指定的消息隊列上獲取消息,如果消息還沒有到來,則轉入睡眠等待狀態。
第三種:共享內存通信
針對消息緩沖需要占用CPU進行消息復制的缺點,OS提供了一種進程間直接進行數據交換的通信方式。共享內存,顧名思義這種通信方式允許多個進程在外部通信協議或同步,互斥機制的支持下使用同一個內存段進行通信,它是一種最有效的數據通信方式,其特點是沒有中間環節,直接將共享的內存頁面通過附接映射到相互通信的進程各自的虛擬地址空間中,從而使多個進程可以直接訪問同一個物理內存頁面。
每個進程的用戶地址空間都是獨立的,一般而言是不能互相訪問的,但內核空間是每個進程都共享的,所以進程之間要通信必須通過內核。
上面命令行里的「|」豎線就是一個管道,它的功能是將前一個命令(ps auxf)的輸出,作為后一個命令(grep mysql)的輸入,從這功能描述,可以看出管道傳輸數據是單向的,如果想相互通信,我們需要創建兩個管道才行。
同時,我們得知上面這種管道是沒有名字,所以「|」表示的管道稱為匿名管道,用完了就銷毀。
管道還有另外一個類型是命名管道,也被叫做 FIFO,因為數據是先進先出的傳輸方式。
在使用命名管道前,先需要通過 mkfifo 命令來創建,并且指定管道名字
myPipe 就是這個管道的名稱,基于 Linux 一切皆文件的理念,所以管道也是以文件的方式存在,我們可以用 ls 看一下,這個文件的類型是 p,也就是 pipe(管道) 的意思:
你操作了后,你會發現命令執行后就停在這了,這是因為管道里的內容沒有被讀取,只有當管道里的數據被讀完后,命令才可以正常退出。
于是,我們執行另外一個命令來讀取這個管道里的數據:
可以看到,管道里的內容被讀取出來了,并打印在了終端上,另外一方面,echo 那個命令也正常退出了。
我們可以看出,管道這種通信方式效率低,不適合進程間頻繁地交換數據。當然,它的好處,自然就是簡單,同時也我們很容易得知管道里的數據已經被另一個進程讀取了。
前面說到管道的通信方式是效率低的,因此管道不適合進程間頻繁地交換數據。
對于這個問題,消息隊列的通信模式就可以解決。比如,A 進程要給 B 進程發送消息,A 進程把數據放在對應的消息隊列后就可以正常返回了,B 進程需要的時候再去讀取數據就可以了。同理,B 進程要給 A 進程發送消息也是如此。
再來,消息隊列是保存在內核中的消息鏈表,在發送數據時,會分成一個一個獨立的數據單元,也就是消息體(數據塊),消息體是用戶自定義的數據類型,消息的發送方和接收方要約定好消息體的數據類型,所以每個消息體都是固定大小的存儲塊,不像管道是無格式的字節流數據。如果進程從消息隊列中讀取了消息體,內核就會把這個消息體刪除。
消息隊列生命周期隨內核,如果沒有釋放消息隊列或者沒有關閉操作系統,消息隊列會一直存在,而前面提到的匿名管道的生命周期,是隨進程的創建而建立,隨進程的結束而銷毀。
消息這種模型,兩個進程之間的通信就像平時發郵件一樣,你來一封,我回一封,可以頻繁溝通了。
但郵件的通信方式存在不足的地方有兩點,一是通信不及時,二是附件也有大小限制,這同樣也是消息隊列通信不足的點。
消息隊列不適合比較大數據的傳輸,因為在內核中每個消息體都有一個最大長度的限制,同時所有隊列所包含的全部消息體的總長度也是有上限。在 Linux 內核中,會有兩個宏定義 MSGMAX 和 MSGMNB,它們以字節為單位,分別定義了一條消息的最大長度和一個隊列的最大長度。
消息隊列通信過程中,存在用戶態與內核態之間的數據拷貝開銷,因為進程寫入數據到內核中的消息隊列時,會發生從用戶態拷貝數據到內核態的過程,同理另一進程讀取內核中的消息數據時,會發生從內核態拷貝數據到用戶態的過程。
消息隊列的讀取和寫入的過程,都會有發生用戶態與內核態之間的消息拷貝過程。那共享內存的方式,就很好的解決了這一問題。
現代操作系統,對于內存管理,采用的是虛擬內存技術,也就是每個進程都有自己獨立的虛擬內存空間,不同進程的虛擬內存映射到不同的物理內存中。所以,即使進程 A 和 進程 B 的虛擬地址是一樣的,其實訪問的是不同的物理內存地址,對于數據的增刪查改互不影響。
用了共享內存通信方式,帶來新的問題,那就是如果多個進程同時修改同一個共享內存,很有可能就沖突了。例如兩個進程都同時寫一個地址,那先寫的那個進程會發現內容被別人覆蓋了。
為了防止多進程競爭共享資源,而造成的數據錯亂,所以需要保護機制,使得共享的資源,在任意時刻只能被一個進程訪問。正好,信號量就實現了這一保護機制。
信號量其實是一個整型的計數器,主要用于實現進程間的互斥與同步,而不是用于緩存進程間通信的數據。
信號量表示資源的數量,控制信號量的方式有兩種原子操作:
P 操作是用在進入共享資源之前,V 操作是用在離開共享資源之后,這兩個操作是必須成對出現的。
接下來,舉個例子,如果要使得兩個進程互斥訪問共享內存,我們可以初始化信號量為 1。
具體的過程如下:
可以發現,信號初始化為 1,就代表著是互斥信號量,它可以保證共享內存在任何時刻只有一個進程在訪問,這就很好的保護了共享內存。
另外,在多進程里,每個進程并不一定是順序執行的,它們基本是以各自獨立的、不可預知的速度向前推進,但有時候我們又希望多個進程能密切合作,以實現一個共同的任務。
例如,進程 A 是負責生產數據,而進程 B 是負責讀取數據,這兩個進程是相互合作、相互依賴的,進程 A 必須先生產了數據,進程 B 才能讀取到數據,所以執行是有前后順序的。
那么這時候,就可以用信號量來實現多進程同步的方式,我們可以初始化信號量為 0。
具體過程:
可以發現,信號初始化為 0,就代表著是同步信號量,它可以保證進程 A 應在進程 B 之前執行。
跨機器進程間通信方式
同個進程下的線程之間都是共享進程的資源,只要是共享變量都可以做到線程間通信,比如全局變量,所以對于線程間關注的不是通信方式,而是關注多線程競爭共享資源的問題,信號量也同樣可以在線程間實現互斥與同步:
網站名稱:包含linux進程間通信命令的詞條
新聞來源:http://vcdvsql.cn/article32/heoppc.html
成都網站建設公司_創新互聯,為您提供微信小程序、網站制作、電子商務、網站設計公司、標簽優化、網站建設
聲明:本網站發布的內容(圖片、視頻和文字)以用戶投稿、用戶轉載內容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網站立場,如需處理請聯系客服。電話:028-86922220;郵箱:631063699@qq.com。內容未經允許不得轉載,或轉載時需注明來源: 創新互聯