進(jìn)程間通信-0722linux高級(jí)_第1頁(yè)
進(jìn)程間通信-0722linux高級(jí)_第2頁(yè)
進(jìn)程間通信-0722linux高級(jí)_第3頁(yè)
進(jìn)程間通信-0722linux高級(jí)_第4頁(yè)
進(jìn)程間通信-0722linux高級(jí)_第5頁(yè)
免費(fèi)預(yù)覽已結(jié)束,剩余30頁(yè)可下載查看

下載本文檔

版權(quán)說(shuō)明:本文檔由用戶(hù)提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

實(shí)驗(yàn)三

使用Linux高級(jí)IPC提綱結(jié)束進(jìn)程間通信概述目標(biāo)問(wèn)題——哲學(xué)家進(jìn)餐問(wèn)題問(wèn)題描述錯(cuò)誤與不好的解法并行度較高的解法Linux高級(jí)IPC機(jī)制概述SystemV信號(hào)燈SystemV共享內(nèi)存區(qū)實(shí)現(xiàn)的其他問(wèn)題實(shí)習(xí)題進(jìn)程間通信概述(1):引子#include<unistd.h>

#include<sys/types.h>

intresult;

main()

{

pid_tpid;

result=0;

pid=fork();

if(pid<0)exit(-1);if(pid){

pid=fork();

if(pid<0)exit(-1);

if(pid==0){

sleep(3);

result=result+20;

exit(0);

}

}else{

sleep(3);

result=result+10;

exit(0);

}

while(wait((int*)0)!=-1);

printf("%d\n",result);

exit(0);

}輸出結(jié)果是什么?進(jìn)程間通信概述(2)進(jìn)程是相互獨(dú)立的,進(jìn)程間的通信需要專(zhuān)門(mén)的機(jī)制。進(jìn)程之間的通信可以經(jīng)由文件系統(tǒng),但實(shí)際使用較為復(fù)雜(例如,需要鎖機(jī)制)。UNIXIPC(InterProcessCommunication)機(jī)制是各種進(jìn)程通信方式的統(tǒng)稱(chēng)。Linux下的進(jìn)程通信手段基本上是從Unix平臺(tái)上的進(jìn)程通信手段繼承而來(lái)的。進(jìn)程間通信概述(3)對(duì)于UNIX的發(fā)展,貝爾實(shí)驗(yàn)室和BSD在進(jìn)程間通信方面的側(cè)重點(diǎn)有所不同:貝爾實(shí)驗(yàn)室對(duì)Unix早期的進(jìn)程間通信手段進(jìn)行了系統(tǒng)的改進(jìn)和擴(kuò)充,形成了“SystemVIPC”,通信進(jìn)程局限在單個(gè)計(jì)算機(jī)內(nèi);BSD則主要考慮跨計(jì)算機(jī)的進(jìn)程間通信,形成了基于套接口(socket)的進(jìn)程間通信機(jī)制。進(jìn)程間通信概述(4)返回最初的UNIXIPCSystemVIPC基于Socket的IPCLinuxIPCPOSIXIPC最初的UnixIPC:信號(hào)、管道、FIFO;SystemVIPC:消息隊(duì)列、信號(hào)量、共享內(nèi)存區(qū);POSIXIPC:消息隊(duì)列、信號(hào)量、共享內(nèi)存區(qū)。哲學(xué)家進(jìn)餐問(wèn)題的描述五個(gè)哲學(xué)家圍坐在一張圓桌周?chē)?,每個(gè)哲學(xué)家面前都有一碗米飯,相鄰的兩碗之間有一支筷子(如圖)。哲學(xué)家的生活包含兩種活動(dòng):即吃飯和思考。當(dāng)一個(gè)哲學(xué)家覺(jué)得餓時(shí),他就試圖分兩次去取他左邊和右邊的筷子,每次拿起一支,但不分次序。如果成功地獲得了一雙筷子,他就開(kāi)始吃飯,吃完以后放下筷子繼續(xù)思考。這樣,問(wèn)題就是,為每個(gè)哲學(xué)家寫(xiě)一段程序來(lái)描述其行為,要求不死鎖。返回錯(cuò)誤與不好的解法(1)解法一:可能進(jìn)入“死鎖”狀態(tài)#defineN5voidphilosopher(inti){while(TRUE){think();take-chopstick(i);take-chopstick((i+1)%N);eat();put-chopstick(i);put-chopstick((i+1)%N);}}若每個(gè)哲學(xué)家進(jìn)程都運(yùn)行到此句后發(fā)生進(jìn)程切換,則進(jìn)入死鎖。錯(cuò)誤與不好的解法(2)#defineN5voidphilosopher(inti){while(TRUE){think();do{take-chopstick(i);if(can-take-chopstick((i+1)%N))break;elseput-chopstick(i);}while(TRUE);eat();put-chopstick(i);put-chopstick((i+1)%N);}}解法二:可能進(jìn)入“饑餓”狀態(tài)不妨假設(shè)此函數(shù)能做到“測(cè)試且設(shè)置”。這種解法可能會(huì)造成下面情況:哲學(xué)家們不斷地重復(fù)“拿起各自左邊的筷子又放下”的動(dòng)作,誰(shuí)也不能進(jìn)餐。注意:這時(shí)和解法一的狀態(tài)不同,這時(shí)進(jìn)程都沒(méi)有阻塞。錯(cuò)誤與不好的解法(3)#defineN5typedefintsemaphore;semaphoremutex=1;voidphilosopher(inti){while(TRUE){think();down(mutex);take-chopstick(i);take-chopstick((i+1)%N);eat();put-chopstick(i);put-chopstick((i+1)%N);up(mutex);}}返回解法三:可行但效率低下

本解法從理論上可行,但從實(shí)際角來(lái)看,有一局限性:同一時(shí)刻只能有一位哲學(xué)家進(jìn)餐。而這里有五支筷子,實(shí)際上應(yīng)能允許兩位哲學(xué)家同時(shí)進(jìn)餐。并行度較高的解法(1)#defineN 5#defineLEFT (i+N-1)%N#defineRIGHT (i+1)%N#defineTHINKING 0#defineHUNGRY 1#defineEATING 2typedefintsemaphore;intstate[N];semaphoremutex=1;semaphores[N];voidphilosopher(inti)

{

while(TRUE){

think();

take-chopsticks(i);

eat();

put-chopsticks(i);

}

}并行度較高的解法(2)返回voidput-chopsticks(inti){down(&mutex);state[i]=THINKING;test(LEFT);test(RIGHT);up(&mutex);}voidtest(i){if(state[i]==HUNGRY

&&state[LEFT]!=EATING&&state[RIGHT]!=EATING){state[i]=EATING;up(&s[i]);}}voidtake-chopsticks(inti){down(&mutex);state[i]=HUNGRY;test(i);up(&mutex);down(&s[i]);}概述SystemVIPC包含了三種機(jī)制,在實(shí)現(xiàn)“哲學(xué)家進(jìn)餐問(wèn)題”時(shí),我們只使用信號(hào)燈機(jī)制和共享存儲(chǔ)區(qū)機(jī)制。主要的函數(shù)如下: 信號(hào)燈 共享內(nèi)存區(qū)頭文件 <sys/sem.h> <sys/shm.h>

創(chuàng)建或打開(kāi)IPC semget shmget控制IPC操作 semctl shmctl

IPC操作函數(shù)

semop shmat,shmdtSystemVIPC對(duì)象以key_t類(lèi)型的值作為其名字。SystemVIPC對(duì)象以一定的存取權(quán)限來(lái)控制其訪(fǎng)問(wèn)。返回SystemVIPC的名字SystemVIPC是有名的,這樣可以支持無(wú)親緣關(guān)系的進(jìn)程訪(fǎng)問(wèn)同一的IPC對(duì)象。其名字的類(lèi)型為key_t,可以由ftok函數(shù)賦予或直接取值IPC_PRIVATE。ftok函數(shù)原型:#include<sys/types.h>

#include<sys/ipc.h>

key_tftok(constchar*pathname,intid);功能:把已存在的路徑名和一整數(shù)標(biāo)識(shí)符轉(zhuǎn)換成一個(gè)key_t值,稱(chēng)為IPC鍵。返回值:成功時(shí)返回IPC鍵,出錯(cuò)返回-1。說(shuō)明:1、ftok產(chǎn)生的鍵值不會(huì)是IPC_PRIVATE;

2、不能保證ftok生成的鍵值唯一;

3、用于產(chǎn)生鍵的文件不能在該IPC對(duì)象存活其 內(nèi)刪除。返回SystemVIPC對(duì)象的存取權(quán)限為防止共享的IPC對(duì)象被非法訪(fǎng)問(wèn),必須為IPC對(duì)象設(shè)置存取權(quán)限。SystemVIPC對(duì)象的存取權(quán)限和文件系統(tǒng)中文件的存取權(quán)限類(lèi)似,也用9位分3組表示,三組分別代表屬主、組成員和其他用戶(hù)對(duì)該IPC對(duì)象的存取權(quán)限;每組中三位,只用其中的兩位表示是否可讀和是否可寫(xiě)。一般為了安全,在創(chuàng)建IPC對(duì)象時(shí)應(yīng)該設(shè)置存取權(quán)限制為0600,表示僅僅對(duì)屬主是可讀,可寫(xiě)的。返回SystemV信號(hào)燈semgetsemctlsemopdown和up的實(shí)現(xiàn)返回semget(1)——函數(shù)說(shuō)明原型:#include<sys/types.h>

#include<sys/ipc.h>

#include<sys/sem.h>

intsemget(key_tkey,intnsems,intoflag);功能:創(chuàng)建或打開(kāi)信號(hào)燈集合。返回值:成功返回非負(fù)信號(hào)燈標(biāo)識(shí)符,出錯(cuò)返回-1。說(shuō)明:1、key是欲創(chuàng)建或打開(kāi)的信號(hào)燈集合的名字;

2、nsems指明信號(hào)燈集合中包含的信號(hào)燈數(shù);

3、oflag是一個(gè)位信息標(biāo)志,含兩部分信息,即存

取權(quán)限和控制字段。低9位表示存取權(quán)限,控

制字段中IPC_CREAT位和IPC_EXCL位的設(shè)

置情況與參數(shù)key共同決定了本調(diào)用的操作。semget(2)——工作流程if(key==IPC_PRIVATE)

創(chuàng)建新信號(hào)燈集并返回其id;

elseif(與key相關(guān)的信號(hào)燈集合存在)if((oflag&IPC_CREAT)&&(oflag&IPC_EXCL))

返回-1;elseif(訪(fǎng)問(wèn)權(quán)限允許)

返回與key相關(guān)的信號(hào)燈集id;else

返回-1;elseif(oflag&IPC_CREAT)

創(chuàng)建新信號(hào)燈集并返回其id;else

返回-1;返回semctl(1)——函數(shù)說(shuō)明原型:#include<sys/types.h>

#include<sys/ipc.h>

#include<sys/sem.h>

intsemctl(intsemid,intsemnum,intcmd,

unionsemunarg);功能:對(duì)semid標(biāo)識(shí)的信號(hào)燈集合進(jìn)行控制。返回值:成功返回非負(fù)值,出錯(cuò)返回-1。說(shuō)明:1、cmd是對(duì)信號(hào)燈集的控制命令,有GETVAL,

SETVAL,GETALL,SETALL,IPC_RMID

等,我們只用最后的兩個(gè)。

2、semnum標(biāo)識(shí)該信號(hào)燈集中某成員(以0為第

一個(gè)),僅用于GETVAL,SETVAL等命令。

3、arg是可選的,取決于參數(shù)cmd,GETALL或

SETALL等命令就要用到參數(shù)arg。semctl(2)——unionsemununionsemun的定義為:

unionsemun{

intval; //僅用于SETVAL命令

structsemid_ds*buf; //用于IPC_SET等命令

ushort*array; //用于SETALL等命令

}注意,本聯(lián)合未在出現(xiàn)在任何系統(tǒng)頭文件中,因此必須由應(yīng)用程序聲明。返回semop(1)——函數(shù)說(shuō)明原型:#include<sys/types.h>

#include<sys/ipc.h>

#include<sys/sem.h>

intsemop(intsemid,

structsembuf*opsptr,

size_tnops);功能:對(duì)semid標(biāo)識(shí)的信號(hào)燈集合中信號(hào)燈進(jìn)行操作。返回值:成功返回0,出錯(cuò)返回-1。說(shuō)明:1、opsptr是指向結(jié)構(gòu)structsembuf的指針,可

以是這種類(lèi)型的結(jié)構(gòu)數(shù)組的頭指針。數(shù)組的每

個(gè)元素包含對(duì)信號(hào)燈集合中一個(gè)信號(hào)的的操作

的信息,從而可實(shí)現(xiàn)同時(shí)對(duì)多信號(hào)燈的操作。

2、nops指出opsptr指向的結(jié)構(gòu)數(shù)組中元素?cái)?shù)。semop(2)——structsembufstructsembuf的定義為:

structsembuf{

shortsem_num; //信號(hào)燈號(hào):0,1,…,nsems-1

shortsem_op; //信號(hào)燈操作:<0,0,>0

shortsem_flg; //操作標(biāo)識(shí):這里我們只要置0

}sem_op不同值對(duì)應(yīng)的操作(設(shè)信號(hào)燈當(dāng)前值為sv):sem-op<0:

start:if(sv>=abs(sem_op))

sv=sv-abs(sem_op);

else{sleep;gotostart;}sem_op>0:

sv=sv+sem_op;喚醒所有阻塞于該信號(hào)量的進(jìn)程;sem_op==0:測(cè)試sv是否為0。返回down和up的實(shí)現(xiàn)voiddown(intsid,intsn){structsembufop;op.sem_num=sn;op.sem_op=-1;op.sem_flg=0;semop(sid,&op,1);}voidup(intsid,intsn){structsembufop;op.sem_num=sn;op.sem_op=1;op.sem_flg=0;semop(sid,&op,1);}返回SystemV共享內(nèi)存區(qū)shmgetshmctlshmat和shmdt使用共享內(nèi)存區(qū)的一般流程返回shmget原型:#include<sys/types.h>

#include<sys/ipc.h>

#include<sys/shm.h>

intshmget(key_tkey,size_tsize,intoflag);功能:創(chuàng)建或打開(kāi)共享內(nèi)存區(qū)。返回值:成功返回非負(fù)內(nèi)存區(qū)標(biāo)識(shí)符,出錯(cuò)返回-1。說(shuō)明:1、size指明共享內(nèi)存區(qū)大?。ㄗ止?jié)為單位);

2、key和oflag的說(shuō)明基本和semget相同;

3、打開(kāi)或創(chuàng)建一個(gè)共享內(nèi)存區(qū),并沒(méi)提供調(diào)用進(jìn)

程訪(fǎng)問(wèn)該內(nèi)存區(qū)的手段。必須調(diào)用shmat。返回shmctl原型:#include<sys/types.h>

#include<sys/ipc.h>

#include<sys/shm.h>

intshmctl(intshmid,intcmd,

structshmid_ds*buff);功能:對(duì)shmid標(biāo)識(shí)的共享內(nèi)存區(qū)進(jìn)行控制。返回值:成功返回0,出錯(cuò)返回-1。說(shuō)明:1、參數(shù)cmd是對(duì)共享內(nèi)存區(qū)的控制命令,可以是

IPC_RMID,IPC_SET或IPC_STAT,我們僅

用第一個(gè);

2、buff主要用于命令I(lǐng)PC_SET和IPC_STAT,命

令為IPC_RMID時(shí)可直接提供NULL;返回shmat和shmdt原型:#include<sys/types.h>

#include<sys/ipc.h>

#include<sys/shm.h>

void*shmat(intshmid,

constvoid*shmaddr,

intflag);

intshmdt(constvoid*shmaddr);功能:shmat用于將一個(gè)打開(kāi)的共享內(nèi)存區(qū)附接到調(diào)用進(jìn)程的地址空間。shmdt用于切斷這個(gè)內(nèi)存區(qū)域。返回值:出錯(cuò)返回-1,shmat成功返回映射區(qū)的起始地址而shmdt成功時(shí)候返回0。說(shuō)明:shmat中shmaddr和flag可用來(lái)影響映射區(qū)起始地址的選取。一般應(yīng)該分別提供NULL和0。返回使用共享內(nèi)存區(qū)的一般流程使用SystemV共享內(nèi)存區(qū)時(shí)的一般流程:用shmget創(chuàng)建或打開(kāi)一個(gè)共享內(nèi)存區(qū)用shmat將打開(kāi)的共享內(nèi)存區(qū)附接到進(jìn)程地址空間對(duì)共享內(nèi)存區(qū)進(jìn)行操作用shmdt切斷共享內(nèi)存區(qū)與本進(jìn)程地址空間的聯(lián)系用shmctl拆除共享內(nèi)存區(qū)(用命令I(lǐng)PC_RMID)返回實(shí)現(xiàn)的其他問(wèn)題如何創(chuàng)建多個(gè)進(jìn)程創(chuàng)建一個(gè)進(jìn)程鏈創(chuàng)建一個(gè)進(jìn)程扇創(chuàng)建一個(gè)進(jìn)程樹(shù)程序的結(jié)束程序失敗后如何釋放資源返回創(chuàng)建一個(gè)進(jìn)程鏈#defineN4#include<stdio.h>#include<sys/types.h>#include<unistd.h>main(){inti;

for(i=1;i<N;++i)if(fork())break;

fprintf(stderr,"#%disprocess%ldwithparent%ld\n",i,(long)getpid(),(long)getppid());}

注意:本程序未考慮fork失敗的情況。1234返回創(chuàng)建一個(gè)進(jìn)程扇#defineN4#include<stdio.h>#include<sys/types.h>#include<unistd.h>main(){inti;

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶(hù)所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶(hù)上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶(hù)上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶(hù)因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論