技術(shù)員聯(lián)盟提供win764位系統(tǒng)下載,win10,win7,xp,裝機(jī)純凈版,64位旗艦版,綠色軟件,免費(fèi)軟件下載基地!

當(dāng)前位置:主頁(yè) > 教程 > 服務(wù)器類 >

Linux進(jìn)程通信(IPC)方式簡(jiǎn)介

來(lái)源:技術(shù)員聯(lián)盟┆發(fā)布時(shí)間:2018-10-19 00:26┆點(diǎn)擊:

  linux下進(jìn)程間通信的幾種主要方式:管道(pipe)和有名管道(FIFO)、信號(hào)(signal)、消息隊(duì)列、共享內(nèi)存(shared memory)、信號(hào)量(semaphore)、套接字(socket),本文對(duì)這些做簡(jiǎn)單介紹

  進(jìn)程間通信的目的

  數(shù)據(jù)傳輸:一個(gè)進(jìn)程需要將它的數(shù)據(jù)發(fā)送給另一個(gè)進(jìn)程,發(fā)送的數(shù)據(jù)量在一個(gè)字節(jié)到幾兆字節(jié)之間。

  共享數(shù)據(jù):多個(gè)進(jìn)程想要操作共享數(shù)據(jù),一個(gè)進(jìn)程對(duì)共享數(shù)據(jù)的修改,別的進(jìn)程應(yīng)該立刻看到。

  通知事件:一個(gè)進(jìn)程需要向另一個(gè)或一組進(jìn)程發(fā)送消息,通知它(它們)發(fā)生了某種事件(如進(jìn)程終止時(shí)要通知父進(jìn)程)。

  資源共享:多個(gè)進(jìn)程之間共享同樣的資源。為了作到這一點(diǎn),需要內(nèi)核提供鎖和同步機(jī)制。

  進(jìn)程控制:有些進(jìn)程希望完全控制另一個(gè)進(jìn)程的執(zhí)行(如Debug進(jìn)程),此時(shí)控制進(jìn)程希望能夠攔截另一個(gè)進(jìn)程的所有陷入和異常,并能夠及時(shí)知道它的狀態(tài)改變。

  進(jìn)程通信方式

  linux下進(jìn)程間通信的幾種主要方式:

  (1)管道(pipe)和有名管道(FIFO)

  (2)信號(hào)(signal)

  (3)消息隊(duì)列

  (4)共享內(nèi)存(shared memory)

  (5)信號(hào)量(semaphore)

  (6)套接字(socket)

  管道

  管道(pipe)及有名管道(named pipe):管道可用于具有親緣關(guān)系進(jìn)程間的通信,有名管道克服了管道沒(méi)有名字的限制,因此,除具有管道所具有的功能外,它還允許無(wú)親緣關(guān)系進(jìn)程間的通信。

  管道是單向的、先進(jìn)先出的、無(wú)結(jié)構(gòu)的、固定大小的字節(jié)流,它把一個(gè)進(jìn)程的標(biāo)準(zhǔn)輸出和另一個(gè)進(jìn)程的標(biāo)準(zhǔn)輸入連接在一起。寫進(jìn)程在管道的尾端寫入數(shù)據(jù),讀進(jìn)程在管道的首端讀出數(shù)據(jù)。數(shù)據(jù)讀出后將從管道中移走,其它讀進(jìn)程都不能再讀到這些數(shù)據(jù)。管道提供了簡(jiǎn)單的流控制機(jī)制。進(jìn)程試圖讀空管道時(shí),在有數(shù)據(jù)寫入管道前,進(jìn)程將一直阻塞。同樣,管道已經(jīng)滿時(shí),進(jìn)程再試圖寫管道,在其它進(jìn)程從管道中移走數(shù)據(jù)之前,寫進(jìn)程將一直阻塞。通常有種限制,一是半雙工,只能單向傳輸;二是只能在父子進(jìn)程間使用。

  有名管道(也叫FIFO,因?yàn)楣艿拦ぷ髟谙热胂瘸龅脑瓌t下,第一個(gè)寫入管道的數(shù)據(jù)也是第一個(gè)被讀出的數(shù)據(jù))。與管道不同,F(xiàn)IFO不是臨時(shí)的對(duì)象,它們是文件系統(tǒng)中真正的實(shí)體,可以用mkfifo命令創(chuàng)建。只要有合適的訪問(wèn)權(quán)限,進(jìn)程就可以使用FIFO。FIFO的打開方式和管道稍微不同。一個(gè)管道(它的兩個(gè)file數(shù)據(jù)結(jié)構(gòu)、VFS I節(jié)點(diǎn)和共享數(shù)據(jù)頁(yè))是一次性創(chuàng)建的,而FIFO已經(jīng)存在,可以由它的用戶打開和關(guān)閉。Linux必須處理在寫進(jìn)程打開FIFO之前讀進(jìn)程對(duì)它的打開,也必須處理在寫進(jìn)程寫數(shù)據(jù)之前讀進(jìn)程對(duì)管道的讀。除此以外,F(xiàn)IFO幾乎和管道的處理完全一樣,而且它們使用一樣的數(shù)據(jù)結(jié)構(gòu)和操作。

  信號(hào)

  信號(hào)(signal):信號(hào)是比較復(fù)雜的通信方式,用于通知接受進(jìn)程有某種事件發(fā)生,除了用于進(jìn)程間通信外,進(jìn)程還可以發(fā)送信號(hào)給進(jìn)程本身;linux除了支持Unix早期信號(hào)語(yǔ)義函數(shù)sigal外,還支持語(yǔ)義符合Posix.1標(biāo)準(zhǔn)的信號(hào)函數(shù)sigaction(實(shí)際上,該函數(shù)是基于BSD的,BSD為了實(shí)現(xiàn)可靠信號(hào)機(jī)制,又能夠統(tǒng)一對(duì)外接口,用sigaction函數(shù)重新實(shí)現(xiàn)了signal函數(shù))。

  信號(hào)是在軟件層次上對(duì)中斷機(jī)制的一種模擬,是一種異步通信方式。

  信號(hào)可以直接進(jìn)行用戶空間進(jìn)程和內(nèi)核進(jìn)程之間的交互,內(nèi)核進(jìn)程也可以利用它來(lái)通知用戶空間進(jìn)程發(fā)生了哪些系統(tǒng)事件。它可以在任何時(shí)候發(fā)給某一進(jìn)程,而無(wú)需知道該進(jìn)程的狀態(tài)。

  如果該進(jìn)程當(dāng)前并未處于執(zhí)行態(tài),則該信號(hào)就由內(nèi)核保存起來(lái),直到該進(jìn)程恢復(fù)執(zhí)行再傳遞給它;如果一個(gè)信號(hào)被進(jìn)程設(shè)置為阻塞,則該信號(hào)的傳遞被延遲,直到其阻塞被取消時(shí)才被傳遞給進(jìn)程 。

  進(jìn)程執(zhí)行信號(hào)的方式:

  忽略信號(hào),即對(duì)信號(hào)不做任何處理,其中,有兩個(gè)信號(hào)不能忽略:SIGKILL及SIGSTOP。

  捕捉信號(hào),定義信號(hào)處理函數(shù),當(dāng)信號(hào)發(fā)生時(shí),執(zhí)行相應(yīng)的處理函數(shù)。

  執(zhí)行缺省操作,Linux對(duì)每種信號(hào)都規(guī)定了默認(rèn)操作。

  消息隊(duì)列

  消息隊(duì)列:消息隊(duì)列是消息的鏈接表,包括Posix消息隊(duì)列System V消息隊(duì)列。有足夠權(quán)限的進(jìn)程可以向隊(duì)列中添加消息,被賦予讀權(quán)限的進(jìn)程則可以讀走隊(duì)列中的消息。消息隊(duì)列克服了信號(hào)承載信息量少,管道只能承載無(wú)格式字節(jié)流以及緩沖區(qū)大小受限等缺點(diǎn)。

  消息隊(duì)列的實(shí)現(xiàn)包括創(chuàng)建或打開消息隊(duì)列、添加消息、讀取消息和控制消息隊(duì)列這四種操作:

  創(chuàng)建或打開消息隊(duì)列使用的函數(shù)是msgget,這里創(chuàng)建的消息隊(duì)列的數(shù)量會(huì)受到系統(tǒng)消息隊(duì)列數(shù)量的限制。

  添加消息使用的函數(shù)是msgsnd函數(shù),它把消息添加到已打開的消息隊(duì)列末尾。

  讀取消息使用的函數(shù)是msgrcv,它把消息從消息隊(duì)列中取走,與FIFO不同的是,這里可以指定取走某一條消息。

  控制消息隊(duì)列使用的函數(shù)是msgctl,它可以完成多項(xiàng)功能。

  信號(hào)量/信號(hào)燈