日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 运维知识 > windows >内容正文

windows

【操作系统】进程间通信的五种方式

發(fā)布時(shí)間:2024/9/30 windows 56 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【操作系统】进程间通信的五种方式 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

  • 引言
  • 1.進(jìn)程對(duì)白:管道、記名管道、套接字
    • 1.管道
    • 2.蟲洞:套接字
    • 3.信號(hào)
  • 4.信號(hào)旗語:信號(hào)量
  • 5.進(jìn)程擁抱:共享內(nèi)存

引言

進(jìn)程作為人類的發(fā)明,自然免不了脫離人類的習(xí)性,也有通信需求。如果進(jìn)程之間不進(jìn)行任何通信,那么進(jìn)程所能完成的任務(wù)就要大打折扣。例如,父進(jìn)程在創(chuàng)建子進(jìn)程后,通常需要監(jiān)督子進(jìn)程的狀態(tài),以便在子進(jìn)程沒有完成給定的任務(wù)時(shí),可以再創(chuàng)建一個(gè)子進(jìn)程來繼續(xù)。這就需要父子進(jìn)程間通信。 進(jìn)程之間的交互稱為進(jìn)程間通信(Inter-Process Communication, IPC)。那么進(jìn)程之間的通信是如何進(jìn)行的呢?

1.進(jìn)程對(duì)白:管道、記名管道、套接字

人們最常使用的通信手段就是對(duì)白。對(duì)白的特點(diǎn)就是一方發(fā)出聲音,另一方接收聲音。而聲音的傳遞則通過空氣(當(dāng)面或無線交談)、線纜(有線電話)進(jìn)行傳遞。類似,進(jìn)程對(duì)白就是一個(gè)進(jìn)程發(fā)出某種數(shù)據(jù)信息,另外一方接收數(shù)據(jù)信息,而這些數(shù)據(jù)信息通過一片共享的存儲(chǔ)空間進(jìn)行傳遞。 在這種方式下,一個(gè)進(jìn)程向這片存儲(chǔ)空間的一端寫入信息,另一個(gè)進(jìn)程從存儲(chǔ)空間的另外一端讀取信息。這看上去像什么?管道。管道所占的空間既可以是內(nèi)存,也可以是磁盤。就像兩人對(duì)白的媒介可以是空氣,也可以是線纜一樣。要?jiǎng)?chuàng)建一個(gè)管道,一個(gè)進(jìn)程只需調(diào)用管道創(chuàng)建的系統(tǒng)調(diào)用即可。該系統(tǒng)調(diào)用所做的事情就是在某種存儲(chǔ)介質(zhì)上劃出一片空間,賦給其中一個(gè)進(jìn)程寫的權(quán)利,另一個(gè)進(jìn)程讀的權(quán)利即可。

1.管道

從根本上說,管道是一個(gè)線性字節(jié)數(shù)組,類似文件,可以使用文件讀寫的方式進(jìn)行訪問。但卻不是文件。因?yàn)橥ㄟ^文件系統(tǒng)看不到管道的存在。另外,我們前面說了,管道可以設(shè)在內(nèi)存里,而文件很少設(shè)在內(nèi)存里(當(dāng)然,有研究人員在研發(fā)基于內(nèi)存的文件系統(tǒng),但這個(gè)還不是主流)。 創(chuàng)建管道在殼命令行下和在程序里是不同的。殼(shell)命令行下,只需要使用符號(hào)“|”即可。例如,在UNIX殼下,我們可以鍵入如下命令: $sort<file1|grep zou 在兩個(gè)utility“排序”(sort)和“查找”(grep)之間創(chuàng)建了一個(gè)管道,數(shù)據(jù)從sort流向grep。即sort的結(jié)果將作為grep的輸入。上述命令的意思是對(duì)file1的內(nèi)容進(jìn)行排序,排完序的結(jié)果作為utility程序grep的輸入,在結(jié)果里面找出所有包括字符串zou的文本行。 在程序里面,創(chuàng)建管道需要使用系統(tǒng)調(diào)用popen()或者pipe()。popen()需要提供一個(gè)目標(biāo)進(jìn)程作為參數(shù),然后在調(diào)用該函數(shù)的進(jìn)程和給出的目標(biāo)進(jìn)程之間創(chuàng)建一個(gè)管道。這很像人們打電話時(shí)必須提供對(duì)方的號(hào)碼,才能創(chuàng)建連接一樣。

在Linux 0.11中,管道操作分為兩部分,一部分是創(chuàng)建管道,另一部分是管道的讀寫操作。
實(shí)例1代碼如下:

#include<stdio.h> #include<unistd.h>int main() {int n,fd[2]; pid _t pid; int i,j; char str1[]="ABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDE ABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDE"; char str2[512]; if(pipe(fd)<0){//創(chuàng)建管道 printf("pipe error\n");return -1; } if((pid=fork())<0){ printf("fork error\n"); return-1;} else if(pid>0)//父進(jìn)程向管道中寫入數(shù)據(jù){ close(fd[0]); for(i=0;i<10000;i++) write(fd[1],str1,strlen(str1));} else{//子進(jìn)程從管道中讀取數(shù)據(jù) close(fd[1]); for(j=0;j<20000;j++) read(fd[0],str2,strlen(str2));} return 0; }

實(shí)例1表現(xiàn)了進(jìn)程間共享數(shù)據(jù)的情景:父進(jìn)程把str1中的數(shù)據(jù)寫入管道,子進(jìn)程從管道中讀出數(shù)據(jù),其中str1中字符長度為1024字節(jié),即1kb

創(chuàng)建時(shí)還需要提供一個(gè)參數(shù)表明管道類型:讀管道或者寫管道。而pipe()調(diào)用將返回兩個(gè)文件描述符(文件描述符是用來識(shí)別一個(gè)文件流的一個(gè)整數(shù),與句柄不同),其中一個(gè)用于從管道進(jìn)行讀操作,一個(gè)用于寫入管道。也就是說,pipe()將兩個(gè)文件描述符連接起來,使得一端可以讀,另一端可以寫。通常情況下,在使用pipe()調(diào)用創(chuàng)建管道后,再使用fork產(chǎn)生兩個(gè)進(jìn)程,這兩個(gè)進(jìn)程使用pipe()返回的兩個(gè)文件描述符進(jìn)行通信。 例如,下面的代碼段創(chuàng)建一個(gè)管道并利用它在父子進(jìn)程間通信。
示例2

int pp[2]; pipe(pp);//創(chuàng)建管道 if(fork()==0){//子進(jìn)程 read(pp[0]);//從父進(jìn)程讀 ……else{ write(pp[1]);//寫給子進(jìn)程

管道的一個(gè)重要特點(diǎn)是使用管道的兩個(gè)進(jìn)程之間必須存在某種關(guān)系,例如,使用popen需要提供另一端進(jìn)程的文件名,使用pipe()的兩個(gè)進(jìn)程則分別隸屬于父子進(jìn)程。

記名管道

如果要在兩個(gè)不相關(guān)的進(jìn)程(如兩個(gè)不同進(jìn)程里面的進(jìn)程)之間進(jìn)行管道通信,則需要使用記名管道。顧名思義,命名管道是一個(gè)有名字的通信管道。記名管道與文件系統(tǒng)共享一個(gè)名字空間,即我們可以從文件系統(tǒng)中看到記名管道。也就是說,記名管道的名字不能與文件系統(tǒng)里的任何文件名重名。例如,在UNIX下使用ls命令可以查看已經(jīng)創(chuàng)建的記名管道。
%ls-l fifo1
prw-r——r——1 john users 0 Sep 22 23:11 fifo1|
一個(gè)進(jìn)程創(chuàng)建一個(gè)記名管道后,另外一個(gè)進(jìn)程可使用open來打開這個(gè)管道(無名管道則不能使用open操作),從而與另外一端進(jìn)行交流。
記名管道的名稱由兩部分組成:計(jì)算機(jī)名和管道名,例如\\[主機(jī)名]\管道\[管道名]\。對(duì)于同一主機(jī)來講,允許有多個(gè)同一命名管道的實(shí)例并且可以由不同的進(jìn)程打開,但是不同的管道都有屬于自己的管道緩沖區(qū)而且有自己的通信環(huán)境,互不影響。命名管道可以支持多個(gè)客戶端連接一個(gè)服務(wù)器端。命名管道客戶端不但可以與本機(jī)上的服務(wù)器通信也可以同其他主機(jī)上的服務(wù)器通信。 管道和記名管道雖然具有簡單、無需特殊設(shè)計(jì)(指應(yīng)用程序方面)就可以和另外一個(gè)進(jìn)程進(jìn)行通信的優(yōu)點(diǎn),但其缺點(diǎn)也很明顯。首先是管道和記名管道并不是所有操作系統(tǒng)都支持。主要支持管道通信方式的是UNIX和類UNIX(如Linux)的操作系統(tǒng)。這樣,如果需要在其他操作系統(tǒng)上進(jìn)行通信,管道機(jī)制就多半會(huì)力不從心了。其次,管道通信需要在相關(guān)的進(jìn)程間進(jìn)行(無名管道),或者需要知道按名字來打開(記名管道),而這 在某些時(shí)候會(huì)十分不便。

2.蟲洞:套接字

套接字(socket)是另外一種可以用于進(jìn)程間通信的機(jī)制。套接字首先在BSD操作系統(tǒng)中出現(xiàn),隨后幾乎滲透到所有主流操作系統(tǒng)中。套接字的功能非常強(qiáng)大,可以支持不同層面、不同應(yīng)用、跨網(wǎng)絡(luò)的通信。使用套接字進(jìn)行通信需要雙方均創(chuàng)建一個(gè)套接字,其中一方作為服務(wù)器方,另外一方作為客戶方。服務(wù)器方必須先創(chuàng)建一個(gè)服務(wù)區(qū)套接字,然后在該套接字上進(jìn)行監(jiān)聽,等待遠(yuǎn)方的連接請(qǐng)求。欲與服務(wù)器通信的客戶則創(chuàng)建一個(gè)客戶套接字,然后向服務(wù)區(qū)套接字發(fā)送連接請(qǐng)求。
服務(wù)器套接字在收到連接請(qǐng)求后,將在服務(wù)器方機(jī)器上創(chuàng)建一個(gè)客戶套接字,與遠(yuǎn)方的客戶機(jī)上的客戶套接字形成點(diǎn)到點(diǎn)的通信通道。之后,客戶方和服務(wù)器方就可以通過send和recv命令在這個(gè)創(chuàng)建的套接字通道上進(jìn)行交流了。 服務(wù)區(qū)套接字有點(diǎn)類似于傳說中的蟲洞(worm hole)
蟲洞的一端是開放的,它在宇宙內(nèi)或宇宙間飄移著,另外一端處于一個(gè)不同的宇宙,監(jiān)聽是否有任何東西從蟲洞來。而欲使用蟲洞者需要找到蟲洞的開口端(發(fā)送連接請(qǐng)求),然后穿越蟲洞即可。
使用套接字進(jìn)行通信稍微有點(diǎn)復(fù)雜,我們下面以一個(gè)網(wǎng)頁瀏覽的例子對(duì)套接字這種通信方式予以說明。對(duì)于一個(gè)網(wǎng)站來說,要想提供正常的網(wǎng)頁瀏覽服務(wù),其網(wǎng)站服務(wù)器需要首先創(chuàng)建一個(gè)服務(wù)區(qū)套接字,作為外界與本服務(wù)器的通信信道。為了使該信道為外人所知,我們通常將該服務(wù)區(qū)套接字與某公共主機(jī)的一個(gè)眾所周知的端口進(jìn)行綁定,如下:

//創(chuàng)建一個(gè)INET的流套接字 serversocket = socket.socket(socket.AF_INET,socket.SOCK_STREAM); //將套接字與某公共主機(jī)的一個(gè)眾所周知的端口綁定 serversocket.bind(socket.gethostname(),80);serversocket.listen(5);//將套接字變?yōu)橐粋€(gè)服務(wù)區(qū)套接字,語句里的數(shù)字5表示端口上的等待隊(duì)列長度限制為5,超過5個(gè)將被拒絕

對(duì)于客戶方來說,如要訪問上述網(wǎng)站,則需要點(diǎn)擊該網(wǎng)站的網(wǎng)址。在點(diǎn)擊網(wǎng)址后(我們這里假定該網(wǎng)站網(wǎng)址為www.sjtu.edu.cn),客戶機(jī)上的網(wǎng)絡(luò)瀏覽器進(jìn)行若干步操作,如下

s = socket.socket(socket.AF_INET,socket.SOCK_STREAM); s.connect("www.sjtu.edu.cn,80);

s.connect命令將向服務(wù)器www.sjtu.edu.cn在端口80打開的服務(wù)器套接字發(fā)送連接請(qǐng)求。而服務(wù)器端在接收到該連接請(qǐng)求后,將生成一個(gè)新的客戶端套接字與該客戶端套接字對(duì)接,從而建立一個(gè)套接字通信信道。如下為網(wǎng)站服務(wù)器上運(yùn)行的主循環(huán)。

while(TRUE) { (clientsocket,address) = serversocket.accept(); newct = client_thread(clientsocket);//對(duì)clientsocket進(jìn)行相關(guān)操作,如創(chuàng)建一個(gè)新進(jìn)程來處理客戶請(qǐng)求 newct.run(); }

至此,套接字通信信道成功創(chuàng)建。客戶端程序可以使用套接字s來發(fā)送請(qǐng)求、索取網(wǎng)頁,而服務(wù)器端則使用套接字clientsocket進(jìn)行發(fā)送和接收消息。 這里需要指出的是服務(wù)區(qū)套接字既不發(fā)送數(shù)據(jù),也不接收數(shù)據(jù)(指不接收正常的用戶數(shù)據(jù),而不是連接請(qǐng)求數(shù)據(jù)),而僅僅生產(chǎn)出“客戶”套接字。當(dāng)其他(遠(yuǎn)方)的客戶套接字發(fā)出一個(gè)連接請(qǐng)求時(shí),我們就創(chuàng)建一個(gè)客戶套接字。一旦創(chuàng)建客戶套接字clientsocket,與客戶的通信任務(wù)就交給了這個(gè)剛剛創(chuàng)建的客戶套接字。而原本的服務(wù)器套接字serversocket則回到其原來的監(jiān)聽操作上。 套接字由于其功能強(qiáng)大而獲得了很大發(fā)展,并出現(xiàn)了許多種類。不同的操作系統(tǒng)均支持或?qū)崿F(xiàn)了某種套接字功能。例如按照傳輸媒介是否為本地,套接字可以分為本地(UNIX域)套接字和網(wǎng)域套接字。而網(wǎng)域套接字又按照其提供的數(shù)據(jù)傳輸特性分為幾個(gè)大類,分別是:
★ 數(shù)據(jù)流套接字(stream socket):提供雙向、有序、可靠、非重復(fù)數(shù)據(jù)通信。
★ 電報(bào)流套接字(datagram socket):提供雙向消息流。數(shù)據(jù)不一定按序到達(dá)。
★ 序列包套接字(sequential packet):提供雙向、有序、可靠連接,包有最大限制。
★ 裸套接字(raw socket):提供對(duì)下層通信協(xié)議的訪問。 套接字從某種程度上來說非常繁雜,各種操作系統(tǒng)對(duì)其處理并不完全一樣。因此,如要了解某個(gè)特定套接字實(shí)現(xiàn),讀者需要查閱關(guān)于該套接字實(shí)現(xiàn)的具體手冊(cè)或相關(guān)文檔。

3.信號(hào)

管道和套接字雖然提供了豐富的通信語義,并且也得到了廣泛應(yīng)用,但它們也存在某些缺點(diǎn),并且在某些時(shí)候,這兩種通信機(jī)制會(huì)顯得很不好用。 首先,如果使用管道和套接字方式來通信,必須事先在通信的進(jìn)程間建立連接(創(chuàng)建管道或套接字),這需要消耗系統(tǒng)資源。其次,通信是自愿的。即一方雖然可以隨意向管道或套接字發(fā)送信息,但對(duì)方卻可以選擇接收的時(shí)機(jī)。即使對(duì)方對(duì)此充耳不聞,你也奈何不得。再次,由于建立連接消耗時(shí)間,一旦建立,我們就想進(jìn)行盡可能多的通信。而如果通信的信息量微小,如我們只是想通知一個(gè)進(jìn)程某件事情的發(fā)生,則用管道和套接字就有點(diǎn)“殺雞用牛刀”的味道,效率十分低下。 因此,我們需要一種不同的機(jī)制來處理如下通信需求:
★ 想迫使一方對(duì)我們的通信立即做出回應(yīng)。
★ 我們不想事先建立任何連接,而是臨時(shí)突然覺得需要與某個(gè)進(jìn)程通信。
★ 傳輸?shù)男畔⒘课⑿?#xff0c;使用管道或套接字不劃算。 應(yīng)付上述需求,我們使用的是信號(hào)(signal)。
那么信號(hào)是什么呢?在計(jì)算機(jī)里,信號(hào)就是一個(gè)內(nèi)核對(duì)象,或者說是一個(gè)內(nèi)核數(shù)據(jù)結(jié)構(gòu)。發(fā)送方將該數(shù)據(jù)結(jié)構(gòu)的內(nèi)容填好,并指明該信號(hào)的目標(biāo)進(jìn)程后,發(fā)出特定的軟件中斷。操作系統(tǒng)接收到特定的中斷請(qǐng)求后,知道是有進(jìn)程要發(fā)送信號(hào),于是到特定的內(nèi)核數(shù)據(jù)結(jié)構(gòu)里查找信號(hào)接收方,并進(jìn)行通知。接到通知的進(jìn)程則對(duì)信號(hào)進(jìn)行相應(yīng)處理。 信號(hào)非常類似我們生活當(dāng)中的電報(bào),如果你想給某人發(fā)一封電報(bào),就擬好電文,將報(bào)文和收?qǐng)?bào)人的信息都交給電報(bào)公司。電報(bào)公司則將電報(bào)發(fā)送到收?qǐng)?bào)人所在地的郵局(中斷),并通知收?qǐng)?bào)人來取電報(bào)。發(fā)報(bào)時(shí)無需收?qǐng)?bào)人事先知道,更無需進(jìn)行任何協(xié)調(diào)。如果對(duì)方選擇不對(duì)信號(hào)做出響應(yīng),則將被操作系統(tǒng)終止運(yùn)行。
示例代碼:
有兩個(gè)用戶進(jìn)程。一個(gè)進(jìn)程用來接收及處理信號(hào),名字叫做processsig。它所對(duì)應(yīng)的程序源代碼如下:

#include<stdio.h> #include<signal.h> void sig_usr(int signo)//處理信號(hào)的函數(shù) { if(signo==SIGUSR1) printf("received SIGUSR1\n");else printf("received%d\n",signo);signal(SIGUSR1,sig_usr);//重新設(shè)置processsig進(jìn)程的信號(hào)處理函數(shù)指針,以便下次使用 } int main(int argc,char ** argv){ signal(SIGUSR1,sig_usr);//掛接processsig進(jìn)程的信號(hào)處理函數(shù)指針 for(;)pause();return 0; } // 另一個(gè)進(jìn)程用來發(fā)送信號(hào),名字叫做sendsig。它所對(duì)應(yīng)的源代碼如下: #include<stdio.h>int main(int argc,char ** argv){ int pid,ret,signo;int i; if(argc!=3{ printf("Usage:sensig<signo><pid>\n";return-1;} signo=atoi(argv[1]);pid=atoi(argv[2]);ret=kill(pid,signo);//這里發(fā)送信號(hào) for(i=0;i<1000000;i++) if(ret!=0) printf("send signal error\n"; return 0;}

操作系統(tǒng)需要具備以下三個(gè)功能,以支持信號(hào)機(jī)制。

  • 系統(tǒng)要支持進(jìn)程對(duì)信號(hào)的發(fā)送和接收 系統(tǒng)在每個(gè)進(jìn)程task_struct中設(shè)置了用以接收信號(hào)的數(shù)據(jù)成員signal(信號(hào)位圖),每個(gè)進(jìn)程接收到的信號(hào)就“按位”存儲(chǔ)在這個(gè)數(shù)據(jù)結(jié)構(gòu)中。系統(tǒng)支持兩種方式給進(jìn)程發(fā)送信號(hào):一種方式是一個(gè)進(jìn)程通過調(diào)用特定的庫函數(shù)給另一個(gè)進(jìn)程發(fā)送信號(hào);另一種方式是用戶通過鍵盤輸入信息產(chǎn)生鍵盤中斷后,中斷服務(wù)程序給進(jìn)程發(fā)送信號(hào)。這兩種方式的信號(hào)發(fā)送原理是相同的,都是通過設(shè)置信號(hào)位圖(signal)上的信號(hào)位來實(shí)現(xiàn)的。

  • 系統(tǒng)要能夠及時(shí)檢測(cè)到進(jìn)程接收到的信號(hào) 系統(tǒng)通過兩種方式來檢測(cè)進(jìn)程是否接收到信號(hào):一種方式是在系統(tǒng)調(diào)用返回之前檢測(cè)當(dāng)前進(jìn)程是否接收到信號(hào);另一種方式是時(shí)鐘中斷產(chǎn)生后,其中斷服務(wù)程序執(zhí)行結(jié)束之前,檢測(cè)當(dāng)前進(jìn)程是否接收到信號(hào)。

  • 系統(tǒng)要支持進(jìn)程對(duì)信號(hào)進(jìn)行處理 系統(tǒng)要能夠保證,當(dāng)用戶進(jìn)程不需要處理信號(hào)時(shí),信號(hào)處理函數(shù)完全不參與用戶進(jìn)程的執(zhí)行;當(dāng)用戶進(jìn)程需要處理信號(hào)時(shí),進(jìn)程的程序?qū)簳r(shí)停止執(zhí)行,轉(zhuǎn)而去執(zhí)行信號(hào)處理函數(shù),待信號(hào)處理函數(shù)執(zhí)行完畢后,進(jìn)程程序?qū)摹皶和5默F(xiàn)場處”繼續(xù)執(zhí)行。

  • 4.信號(hào)旗語:信號(hào)量

    信號(hào)量(semaphore)是由荷蘭人E.W.Dijkstra在20世紀(jì)60年代所構(gòu)思出的一種程序設(shè)計(jì)構(gòu)造。其原型來源于鐵路的運(yùn)行:在一條單軌鐵路上,任何時(shí)候只能有一列列車行駛在上面(如圖6-9)。而管理這條鐵路的系統(tǒng)就是信號(hào)量。任何一列火車必須等到表明鐵路可以行駛的信號(hào)后才能進(jìn)入軌道。當(dāng)一列列車進(jìn)入單軌運(yùn)行后,需要將信號(hào)改為禁止進(jìn)入,從而防止別的火車同時(shí)進(jìn)入軌道。而當(dāng)列車駛出單軌后,則需要將信號(hào)變回允許進(jìn)入狀態(tài)。這很像以前的旗語, 在計(jì)算機(jī)里,信號(hào)量實(shí)際上就是一個(gè)簡單整數(shù)。一個(gè)進(jìn)程在信號(hào)變?yōu)?或者1的情況下推進(jìn),并且將信號(hào)變?yōu)?或0來防止別的進(jìn)程推進(jìn)。當(dāng)進(jìn)程完成任務(wù)后,則將信號(hào)再改變?yōu)?或1,從而允許其他進(jìn)程執(zhí)行。

    5.進(jìn)程擁抱:共享內(nèi)存

    管道、套接字、信號(hào)、信號(hào)量,雖然滿足了多種通信需要,但還是有一種需要未能滿足。這就是兩個(gè)進(jìn)程需要共享大量數(shù)據(jù)。這就像兩個(gè)人,他們互相喜歡,并想要一起生活時(shí)(共享大量數(shù)據(jù)量),打電話、握手、對(duì)白等就顯得不夠了,這個(gè)時(shí)候需要的是擁抱,只有將其緊緊擁抱于懷,感覺才最到位,也才能盡可能地共享。 進(jìn)程的擁抱就是共享內(nèi)存。共享內(nèi)存就是兩個(gè)進(jìn)程共同擁有同一片內(nèi)存。對(duì)于這片內(nèi)存中的任何內(nèi)容,二者均可以訪問。要使用共享內(nèi)存進(jìn)行通信,一個(gè)進(jìn)程首先需要?jiǎng)?chuàng)建一片內(nèi)存空間專門作為通信用,而其他進(jìn)程則將該片內(nèi)存映射到自己的(虛擬)地址空間。這樣,讀寫自己地址空間中對(duì)應(yīng)共享內(nèi)存的區(qū)域時(shí),就是在和其他進(jìn)程進(jìn)行通信。
    共享內(nèi)存有點(diǎn)像管道,有些管道不也是一片共享內(nèi)存嗎?這是形似而神不似。首先,使用共享內(nèi)存機(jī)制通信的兩個(gè)進(jìn)程必須在同一臺(tái)物理機(jī)器上;其次,共享內(nèi)存的訪問方式是隨機(jī)的,而不是只能從一端寫,另一端讀,因此其靈活性比管道和套接字大很多,能夠傳遞的信息也復(fù)雜得多。 共享內(nèi)存的缺點(diǎn)是管理復(fù)雜,且兩個(gè)進(jìn)程必須在同一臺(tái)物理機(jī)器上才能使用這種通信方式。共享內(nèi)存的另外一個(gè)缺點(diǎn)是安全性脆弱。因?yàn)閮蓚€(gè)進(jìn)程存在一片共享的內(nèi)存,如果一個(gè)進(jìn)程染有病毒,很容易就會(huì)傳給另外一個(gè)進(jìn)程。就如同人傳染病毒一樣。
    需要注意的是,使用全局變量在同一個(gè)進(jìn)程的進(jìn)程間實(shí)現(xiàn)通信不稱為共享內(nèi)存。

    總結(jié)

    以上是生活随笔為你收集整理的【操作系统】进程间通信的五种方式的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。