一個故事看懂進程間通訊技術

月黑風高夜,忽然聽得咣噹一聲,Web服務器的目錄下冒出了兩個文件,弄出了不小的聲響。這兩個傢伙一胖一瘦,鬼鬼祟祟,潛入這臺計算機,不知要搞什麼名堂。服務器

「二弟,一下子我們按照計劃好的運行起來,分頭行事,你等我信號,拿到數據後趕忙撤」,胖子對瘦子說到。markdown

「老大,這地方我不熟悉,我怎麼等你信號?我們得想個聯繫方式,一下子通訊使用」,瘦子說到。網絡

「這個不用擔憂,主人都交代好了」,胖子一邊說,一邊從背後拿出一本 《Linux進程間通訊手冊》 翻了起來。socket

信號

翻開手冊的第一頁,上面寫着:信號——Signal,兩個傢伙開始認真研究起來。spa

片刻以後,胖子程序說道:「唉,這個不行,日後翻吧!」code

瘦子程序不解,問道:「咋就不行啦?」orm

「你看這裏,手冊上說了,信號是Linux上的一種軟中斷通訊機制,能夠向指定進程發送通知,總共有64種信號,不過這個信號只能做爲通知使用,沒辦法傳輸數據」繼承

「無法傳輸數據?那這玩意有什麼用?」隊列

「仍是有用啊,能夠通知某個進程發生了什麼事件,好比kill命令就是利用這個信號來告知進程退出從而實現殺進程的效果的」進程

「原來如此」,瘦子程序如有所思的點了點頭,此時胖子已經翻到了手冊的第二頁。

socket

「你看,手冊上寫了,能夠用socket」,胖子說到。

「socket?那不是網絡通訊使用的嗎?」,瘦子有些疑惑。

「是啊,不過我們同樣能夠用來在本地計算機通訊,把鏈接的IP地址換成127.0.0.1就好了」

「感受有點太招搖了,我們計算機內部進程通訊,數據還要通過網卡,很容易被發現的!」

「不會不會,手冊上說了,127.0.0.1是本地迴環地址,數據在協議棧就進行轉發了,根本不會到達網卡」

「那抓包能抓到我們通訊嗎?」

「嗯,讓我看看···手冊上說,能夠在虛擬的迴環網卡lo上抓到數據」

「仍是算了吧,咱幹這事得悄悄進行,不能留下痕跡,你再看看還有沒有別的招」

聽瘦子這麼一說,胖子倒也以爲有理,便在手冊上繼續翻了起來。

匿名管道

「哎,有了有了,這個叫匿名管道的,聽起來就比較隱祕,應該不會被發現。」

瘦子接過手冊,看了起來。

這倆盯着手冊上的兩個圖研究了半天,總算弄明白了,所謂匿名管道不過是內核中的一段緩衝區,提供了讀寫兩個口子,經過fork建立子進程後,子進程繼承了父進程的管道信息,兩邊只要約定好,一個讀,一個寫,就能實現通訊了。

「老大,這匿名管道是單向的,我們要通訊,得整兩根管道才行,一個你寫我讀,一個我寫你讀」

「看起來挺靠譜,就這麼幹!」,二人達成了一致。

胖子程序率先運行起來,隨後建立了兩個管道,一個用來發送消息,一個用來接收消息。接着執行fork,將瘦子程序也運行了起來。

時間過的很快,轉眼已經是深夜,隨着計算機被關掉,兩個傢伙的進程也都退出了。

半夜無人之際,硬盤中這兩個傢伙開始吵起來了。

「你是怎麼回事?我給你發消息怎麼也不回,害得我一連發了一堆消息,最後把管道塞滿了,我都阻塞了!」,胖子程序氣憤地說道。

「嗨!別提了,主人給我寫的程序有bug,今天運行的時候不當心崩潰了,等我再次起來時,發現管道不見了,什麼狀況啊?」,瘦子程序說完嘆了一口氣。

「那確定不行,這匿名管道須要有親緣關係的進程繼承後才能通訊,你用別的方式運行起來,確定看不到我建立的管道啊!」

「這匿名管道用起來太麻煩了,看看還有沒有別的通訊方式?」

胖子程序又掏出了手冊,翻了起來。

消息隊列

「有了有了,這裏還寫了兩種方式:命名管道、消息隊列」,胖子程序說到。

「命名管道?跟匿名管道有什麼區別嗎?」

「命名管道有名字,有了名字就不限有親緣關係的進程才能通訊了,只要使用這個名字,都能打開管道通訊,這下你就算掛了重啓也能跟我聯繫上了」

「那消息隊列又是什麼東西?」

「額,讓我看一下」

「給我也看看」,瘦子程序湊了上去,一塊兒看了起來。

過了一下子,瘦子程序說道:「我看明白了,這消息隊列是內核中的一個消息鏈表,按照消息塊組織,比那管道全是二進制數據流堆積在一塊兒好用多了」

「有道理,並且這消息還能夠指定類型,這樣我們倆就不用弄兩個管道,一個消息隊列就好了,我們倆使用不一樣的消息類型,可省了很多事兒啊!」

「那我們就用消息隊列吧,別用那什麼管道了」

「好,就這麼幹!」

兩個傢伙一拍即合,準備次日再大幹一場。

次日,計算機啓動後,它們又偷偷的運行了起來。

這一次用上了消息隊列,聯絡起來方便了很多。

共享內存

不知過了多久,那瘦子進程總算來信兒了,胖子從消息隊列中取出一看,只見上面寫着:

「老大,我拿到了數據了,須要你來處理一下,不過這數據體量有點大,用管道和消息隊列傳輸效率都過低了,有無辦法快速把數據傳送給你,盼速回。」

胖子進程內心一陣歡喜,數據拿到了,總算能夠回去交差了。不過怎麼樣快速把數據傳送過來呢,內心又犯起了嘀咕。

此時,胖子進程又一次拿出手冊,翻到了最後一頁,發現了一個叫「共享內存」的東西,彷彿像抓住了救命稻草通常,仔細研究了起來。

片刻以後,胖子的臉上露出了笑容,隨後寫下了一條消息給瘦子進程發送了過去。

卻說這瘦子進程正在焦急等待消息中,收到老大的回信後,趕忙取出來看:

二弟,主人的手冊中提到,可使用共享內存進行進程間通訊。
我準備了幾個內存頁面,你將它們映射到你的進程地址空間中,我們就能共享這一片內存,你寫的數據我能當即看到,我寫的你也能當即看到,雖然我們各自讀寫的地址不一樣,但其實是訪問的同一片物理內存頁面,比管道和消息隊列效率高多了!

不過爲了防止我們一塊兒讀寫發生衝突,須要配合信號量一塊兒使用,用它來實現進程間同步。
具體的使用方法以下:
······
······
盼速回!

瘦子進程看完,心中大喜!趕忙經過消息隊列發了一封回信。

隨後,經過老大交代的方法開始操做起來,打開共享、映射掛載一鼓作氣。再接着,將數據一古腦兒寫到了共享的內存頁面中。

大功告成以後,便退出了進程,按照計劃準備撤退,卻不見了胖子的蹤影,既無進程也無文件。

「這傢伙難道拋下我一我的跑了?」

正想着,忽然「嗡」的一聲,瘦子的程序文件也沒了。

卻看那文件目錄之下,只留了一卷《Linux進程間通訊手冊》···

相關文章
相關標籤/搜索