[深入理解linux應(yīng)用]-Linux進(jìn)程間通信方式
環(huán)境:
文章目錄
1、Linux進(jìn)程間通信方式
1.1、管道(Pipe)和命名管道(FIFO)
1.2、消息隊(duì)列(Message Queue)
1.3、共享內(nèi)存(Shared Memory)
1.4、套接字(Socket)
1、Linux進(jìn)程間通信方式
1.1、管道(Pipe)和命名管道(FIFO)
在 Linux 進(jìn)程間通信的方法中,管道和命名管道是最早的進(jìn)程間通信方法之一,管道可以用于具有親緣關(guān)系進(jìn)程間的通信,命名管道克服了管道沒有名字的限制,因此,除具有管道所具有的功能外,他還允許無親緣關(guān)系進(jìn)程間的通信。
管道的特點(diǎn)
管道是 Linux 支持的最初Unix IPC 形式之一,具有以下特點(diǎn):
管道是半雙工的,數(shù)據(jù)只能向一個(gè)方向流動(dòng);需要雙方通信時(shí),需要建立起兩個(gè)管道;
只能用于父子進(jìn)程或者兄弟進(jìn)程之間(具有親緣關(guān)系的進(jìn)程);
單獨(dú)構(gòu)成一種獨(dú)立的文件系統(tǒng):管道對(duì)于管道兩端的進(jìn)程而言,就是一個(gè)文件,但它不是普通的文件,它不屬于某種文件系統(tǒng),而是自立門戶,單獨(dú)構(gòu)成一種文件系統(tǒng),并且只存在于內(nèi)存中。
數(shù)據(jù)的讀寫規(guī)則:一個(gè)進(jìn)程向管道中寫的內(nèi)容被管道另一端的進(jìn)程讀出。寫入的內(nèi)容每次都添加在管道緩沖區(qū)的末尾,并且每次都是從緩沖區(qū)的頭部讀出數(shù)據(jù)。
管道的局限性
管道的主要局限性正體現(xiàn)在它的特點(diǎn)上:
只支持單向數(shù)據(jù)流;
只能用于具有親緣關(guān)系的進(jìn)程之間;
沒有名字;
管道的緩沖區(qū)是有限的(管道存在于內(nèi)存中,在管道創(chuàng)建時(shí),最大只能為緩沖區(qū)分配一個(gè)頁(yè)面大小的空間);
管道所傳送的是無格式字節(jié)流,這就要求管道的讀方和寫方必須事先約定好數(shù)據(jù)的格式。
命名管道
管道應(yīng)用的一個(gè)重大限制是它沒有名字,因此,只能用于具有親緣關(guān)系的進(jìn)程間通信,在命名管道(named pipe 或 FIFO)提出后,這個(gè)限制得到了克服。FIFO不同于管道之處在于它提供一個(gè)路徑名與之關(guān)聯(lián),以 FIFO 的文件形式存在于文件系
統(tǒng)中。這樣,即使與 FIFO 的創(chuàng)建進(jìn)程不存在親緣關(guān)系的進(jìn)程,只要可以訪問該路徑,就能夠彼此通過 FIFO 相互通信(能夠訪問該路徑的進(jìn)程以及 FIFO 的創(chuàng)建進(jìn)程之間),因此,通過 FIFO,不相關(guān)的進(jìn)程也能交換數(shù)據(jù)。值得注意的是,F(xiàn)IFO嚴(yán)格遵循先進(jìn)先出(first in first out)規(guī)則,對(duì)管道及 FIFO 的讀總是從開始處返回?cái)?shù)據(jù),對(duì)它們的寫則把數(shù)據(jù)添加到末尾。
FIFO 可以說是管道的推廣,克服了管道沒有名字的限制,使得無親緣關(guān)系的進(jìn)程同樣可以采用先進(jìn)先出的通信機(jī)制進(jìn)行通信。 管道和 FIFO 的數(shù)據(jù)都是字節(jié)流,應(yīng)用程序之間必須事先確定特定的傳輸"協(xié)議"(即通信雙方約定好的數(shù)據(jù)格式)。所有使用管道的進(jìn)程都必須在事先確保所使用的管道是存在的。
1.2、消息隊(duì)列(Message Queue)
消息隊(duì)列就是一個(gè)消息的鏈表。可以把消息看作一個(gè)記錄,具有特定的格式以及特定的優(yōu)先級(jí)。對(duì)消息隊(duì)列有寫權(quán)限的進(jìn)程可以向隊(duì)列中按照一定的規(guī)則添加新消息;對(duì)消息隊(duì)列有讀權(quán)限的進(jìn)程則可以從消息隊(duì)列中讀走消息。消息隊(duì)列是隨內(nèi)核持續(xù)的。
** 消息隊(duì)列的基本概念 **
消息隊(duì)列是隨內(nèi)核持續(xù)的,只有在內(nèi)核重起或者顯式刪除一個(gè)消息隊(duì)列時(shí),該消息隊(duì)列才會(huì)真正被刪除。
消息隊(duì)列就是一個(gè)消息的鏈表。每個(gè)消息隊(duì)列都有一個(gè)隊(duì)列頭,用結(jié)構(gòu)struct msg_queue 來描述。隊(duì)列頭中包含了該消息隊(duì)列的大量信息,包括消息隊(duì)列的鍵值、用戶 ID、用戶組 ID 以及消息隊(duì)列中消息數(shù)目等等,甚至記錄了最近對(duì)消息隊(duì)列讀寫進(jìn)程的ID。用戶可以訪問這些信息,也可以設(shè)置其中的某些信息。
系統(tǒng)里記錄消息隊(duì)列的數(shù)據(jù)結(jié)構(gòu)(struct ipc_ids msg_ids)位于內(nèi)核中,系統(tǒng)中的所有消息隊(duì)列都可以在結(jié)構(gòu) msg_ids 中找到訪問入口。內(nèi)核和消息隊(duì)列就是通過這個(gè)全局的數(shù)據(jù)結(jié)構(gòu)建立起聯(lián)系的。
** 消息隊(duì)列的操作 **
對(duì)消息隊(duì)列的操作有三種類型:
打開或創(chuàng)建消息隊(duì)列
消息隊(duì)列的內(nèi)核持續(xù)性要求每個(gè)消息隊(duì)列都在系統(tǒng)范圍內(nèi)對(duì)應(yīng)唯一的鍵值,所以,要獲得一個(gè)消息隊(duì)列的描述字,只需提供該消息隊(duì)列的鍵值(key)即可;
讀寫操作
消息隊(duì)列的讀寫操作非常簡(jiǎn)單。對(duì)于隊(duì)列中的每個(gè)消息都有相同的數(shù)據(jù)結(jié)構(gòu),一般情況下,這個(gè)數(shù)據(jù)結(jié)構(gòu)包含兩部分內(nèi)容:一個(gè)代表消息類型的成員(一個(gè)長(zhǎng)整型的變量),從消息隊(duì)列中讀取消息的一個(gè)重要依據(jù)就是消息的類型,與此同時(shí)消息隊(duì)列中消息的優(yōu)先級(jí)也是通過消息的類型實(shí)現(xiàn)的;另一個(gè)成員就是消息的內(nèi)容。因此,對(duì)于發(fā)送消息來說,首先預(yù)設(shè)一個(gè)與消息有相同結(jié)構(gòu)的緩沖區(qū)并寫入消息的類型和內(nèi)容,調(diào)用相應(yīng)的發(fā)送函數(shù)即可;對(duì)讀取消息來說,首先分配一個(gè)與消息有相同結(jié)構(gòu)的緩沖區(qū),然后把消息讀入該緩沖區(qū)即可。
獲得或者設(shè)置消息隊(duì)列屬性
消息隊(duì)列的信息基本上都保存在消息隊(duì)列頭中,因此,可以分配一個(gè)類似于消息隊(duì)列頭的結(jié)構(gòu)(struct msqid_ds),來返回消息隊(duì)列的屬性;同樣可以設(shè)置該數(shù)據(jù)結(jié)構(gòu)。
** 消息隊(duì)列的限制 **
每個(gè)消息隊(duì)列的容量(所能容納的字節(jié)數(shù))都有限制,該值因系統(tǒng)不同而不同。另一個(gè)限制是每個(gè)消息隊(duì)列所能容納的最大消息數(shù)。除了上述兩個(gè)針對(duì)消息隊(duì)列的限制外,系統(tǒng)對(duì)消息隊(duì)列的限制還有系統(tǒng)范圍內(nèi)的最大消息隊(duì)列個(gè)數(shù),以及整個(gè)系統(tǒng)范圍內(nèi)的最大消息數(shù)。一般來說,實(shí)際開發(fā)過程中不會(huì)超過這些限制。
1.3、共享內(nèi)存(Shared Memory)
** System V 共享內(nèi)存 **
共享內(nèi)存允許兩個(gè)或多個(gè)進(jìn)程共享一給定的存儲(chǔ)區(qū),因?yàn)閿?shù)據(jù)不需要來回復(fù)制,所以是最快的一種進(jìn)程間通信機(jī)制。共享內(nèi)存可以通過系統(tǒng)調(diào)用 mmap()映射普通文件(特殊情況下還可以采用匿名映射)機(jī)制實(shí)現(xiàn),也可以通過 system V 的共享內(nèi)存
機(jī)制實(shí)現(xiàn)。進(jìn)程間通信的共享內(nèi)存方法,雖然應(yīng)用接口和原理很簡(jiǎn)單,但是內(nèi)部機(jī)制復(fù)雜。為了實(shí)現(xiàn)更安全通信,往往還與信號(hào)燈等同步機(jī)制共同使用。所以我們?cè)谶@里只做一個(gè)簡(jiǎn)要的介紹。
** 用系統(tǒng)調(diào)用 mmap()實(shí)現(xiàn)共享內(nèi)存 **
1.4、套接字(Socket)
** 概述 **
** 使用套接字時(shí)幾個(gè)重要的數(shù)據(jù)結(jié)構(gòu) **
** 套接字編程中的幾個(gè)重要的系統(tǒng)調(diào)用 **
Linux 任務(wù)調(diào)度
版權(quán)聲明:本文內(nèi)容由網(wǎng)絡(luò)用戶投稿,版權(quán)歸原作者所有,本站不擁有其著作權(quán),亦不承擔(dān)相應(yīng)法律責(zé)任。如果您發(fā)現(xiàn)本站中有涉嫌抄襲或描述失實(shí)的內(nèi)容,請(qǐng)聯(lián)系我們jiasou666@gmail.com 處理,核實(shí)后本網(wǎng)站將在24小時(shí)內(nèi)刪除侵權(quán)內(nèi)容。