當(dāng)前位置:首頁 > 嵌入式培訓(xùn) > 嵌入式學(xué)習(xí) > 講師博文 > 關(guān)于進(jìn)程間通信
關(guān)于進(jìn)程間通信
時間:2018-09-21 來源:未知
在之前的總結(jié)中我們已經(jīng)總結(jié)了線程間通信的方式和提點(diǎn),下面這篇博文我們來總結(jié)下進(jìn)程間通信的方式方法和特點(diǎn)。同樣我們不把函數(shù)作為重點(diǎn),重點(diǎn)在于對特征的中介。
進(jìn)程間通信(IPC)的方式很多。下面進(jìn)行歸類總結(jié)。
在傳統(tǒng)的進(jìn)程間通信中有 無名管道,有名管道,信號通信。后來system v 退出了自己的IPC 方式 消息隊(duì)列,共享內(nèi)存和信號燈集合但是system v的通信方式也存在自己的缺點(diǎn)。POSIX 在此基礎(chǔ)上退出了自己的posix的消息隊(duì)列,共享內(nèi)存和信號燈集。另外,進(jìn)程間還可以通過對文件的操作實(shí)現(xiàn)溝通,這里用到了文件鎖。還有后期的內(nèi)存映射方式。在網(wǎng)絡(luò)上BSD率先提出了socket的方法,成為后來為流行的套接字通信方式,這種方式既可以在本機(jī)上的進(jìn)程間,也可以在網(wǎng)絡(luò)上。

IPC 通信工具分類
下面對我們常用的集中進(jìn)程間通信方式的特征進(jìn)行總結(jié)
pipe
1.32位linux系統(tǒng)下默認(rèn)大小為64M
2.如果寫滿會阻塞知道有人讀走再寫
3.如果讀寫都有那么寫不會影響,讀的話會阻塞
4.如果沒有讀端那么管道寫入后會管道破裂發(fā)送一個信號SIGPIPE導(dǎo)致進(jìn)程結(jié)束
5.如果沒有寫端那么管道讀取會退出,如果管道里有東西那么會先讀出來然后退出
6.fd[0]為讀端 fd[1]為寫端是固定的
7.Pipe創(chuàng)建之后,在內(nèi)核中。當(dāng)所有的讀端和寫端都關(guān)閉的時候,pipe將被釋放掉
fifo
mkfifo既是函數(shù)又是命令
1.fifo不能用標(biāo)準(zhǔn)IO操作。適用于非親緣關(guān)系的進(jìn)程間,大為64M
2.fifo的打開有只讀只寫方式
如果只讀方式打開沒有寫端會阻塞,如果只寫方式?jīng)]有讀端會阻塞這種阻塞是以open處阻塞。
如果以讀寫方式打開則不會阻塞,但是我們一般不會這樣做,用fifo更多用來多個進(jìn)程間進(jìn)行單向的通信
3.fifo 文件不能通過lseek函數(shù)進(jìn)行操作,管道屬于 內(nèi)核空間開辟,如果讀寫端都關(guān)閉那么內(nèi)容會被清除
4.可以通過打開時候設(shè)置全新啊O_NONBLOCK 將打開方式設(shè)置為非阻塞模式,這種模式打開的時候如果另一端已經(jīng)打開那么沒有影響
如果非阻塞為讀,而寫段沒打開,那么讀同樣會成功(就是不會open處阻塞)
如果非阻塞為寫,而讀端沒有打開,那么會返回一個錯誤信號管道破裂ENXIO open調(diào)用失敗
信號
1.引起內(nèi)核產(chǎn)生信號的事件 硬件異常 終端輸入特殊字符 軟件事件如定時器到期,窗口改變
2.信號的默認(rèn)操作 :忽略信號 終止進(jìn)程 暫停進(jìn)程 對之前暫停的進(jìn)程重新啟動
3.信號是一種異步行為
共享內(nèi)存
1.共享內(nèi)存是一種為高效的進(jìn)程間通信方式,內(nèi)核專門留出的一塊內(nèi)存區(qū)域,這塊內(nèi)存可以由需要的訪問的進(jìn)程將其映射到自己的私有空間,因此進(jìn)程可以直接讀取數(shù)據(jù)不需要復(fù)制,所以提高了效率
2.key值是一個非負(fù)整數(shù),通常生成的方法是有ftok生成(傳入一個文件,和一個整數(shù),通過inod節(jié)點(diǎn)結(jié)合算法)。這樣同樣的參數(shù)確保生成的key一樣,而不同的傳入產(chǎn)生不同的key。這樣可以確保打開相同的key即指向相同的共享內(nèi)存(或者消息隊(duì)列或者信號量)。這是一種成熟的技術(shù)
3.共享內(nèi)存多個進(jìn)程可以對其操作,因此需要同步互斥機(jī)制
4.生成key---創(chuàng)建或打開---映射---解除映射----刪除 這是共享內(nèi)存使用的一般步驟
5.映射后一個參數(shù)可設(shè)置只讀,0表示可讀可寫
6.創(chuàng)建時候key如果設(shè)置成私有的,那么只有在這個進(jìn)程中可用,對進(jìn)程間通信沒有多大意義
7.共享內(nèi)存的大小限制: usr/include/linux/shm.h中
#define SHMMAX 0x2000000 大32MB
#define SHMMIN 1 小1個字節(jié)
消息隊(duì)列
1.消息隊(duì)列中一次只能讀取一條消息,不能一次讀取多條或者不到一條
2.消息隊(duì)列中的消息既可以按照先進(jìn)先出讀取也可以按照類型
3.msgsnd 發(fā)送消息事后,第三個參數(shù)為消息的字節(jié)數(shù),一次發(fā)送一個消息所以返回為0,而不需要為發(fā)送的字節(jié)數(shù),
第四個參數(shù)可以設(shè)置為非阻塞模式IPC_NOWAIT,這樣當(dāng)消息隊(duì)列滿的時候會立即返回EAGAIN錯誤
4 msgrcv 也可以設(shè)置非阻塞模式,,如果阻塞那么消息隊(duì)列中沒有消息會阻塞,如果設(shè)置為非阻塞則立即返回ENOMSG錯誤
5.消息隊(duì)列和共享內(nèi)存如果不手動釋放不會隨進(jìn)程結(jié)束,除非系統(tǒng)重啟
6.消息隊(duì)列結(jié)構(gòu)體重的消息類型項(xiàng)必須為第一項(xiàng)
信號
1.信號量更多是用來同步進(jìn)程間資源的,如共享內(nèi)存。也可以同步父子進(jìn)程的執(zhí)行
2信號燈限制: usr/include/linux/sem.h中
semget申請的信號燈的編號從0開始
semctl中的cmd 命令的常用用法
另外在poxis中也有消息隊(duì)列,共享內(nèi)存和信號量的機(jī)制
消息隊(duì)列中system v 的移植性比較好,可以選擇消息類型,但是poxis 的消息隊(duì)列可以被poll select 等進(jìn)行監(jiān)聽
共享內(nèi)存中system v 的支持范圍比較廣泛,但是poxis 不必再創(chuàng)建時候就定下共享內(nèi)存的大小
信號量中 poxis 有些像線程的信號量,通過相互通知的機(jī)制進(jìn)行pv操作,相對而言不那么復(fù)雜。system v中是定義一個信號量的集合

