實(shí)驗(yàn)三-進(jìn)程間通信_(tái)第1頁(yè)
實(shí)驗(yàn)三-進(jìn)程間通信_(tái)第2頁(yè)
實(shí)驗(yàn)三-進(jìn)程間通信_(tái)第3頁(yè)
實(shí)驗(yàn)三-進(jìn)程間通信_(tái)第4頁(yè)
實(shí)驗(yàn)三-進(jìn)程間通信_(tái)第5頁(yè)
已閱讀5頁(yè),還剩9頁(yè)未讀 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡(jiǎn)介

1、實(shí)驗(yàn)三 進(jìn)程間通信(2學(xué)時(shí))一、實(shí)驗(yàn)?zāi)康?1) 了解什么是信號(hào)。(2) 熟悉LINUX系統(tǒng)中進(jìn)程之間軟中斷通信的基本原理。(3) 熟悉LINUX支持的管道通信方式。二、實(shí)驗(yàn)內(nèi)容(1) 編寫(xiě)一段程序,使其現(xiàn)實(shí)進(jìn)程的軟中斷通信。 即:使用系統(tǒng)調(diào)用fork()創(chuàng)建兩個(gè)子進(jìn)程,再用系統(tǒng)調(diào)用signal()讓父進(jìn)程捕捉鍵盤(pán)上來(lái)的中斷信號(hào)(即按 ctrl+c 鍵);當(dāng)捕捉到中斷信號(hào)后,父進(jìn)程用系統(tǒng)調(diào)用kill( )向兩個(gè)子進(jìn)程發(fā)出信號(hào),子進(jìn)程捕捉到信號(hào)后,分別輸出下列信息后終止: Child Process11 is killed by Parent! Child Process12 is killed

2、by Parent! 父進(jìn)程等待兩個(gè)子進(jìn)程終止后,輸出如下的信息后終止 Parent Process is killed!要求:運(yùn)行以下參考程序并分析結(jié)果。<參考程序> #include<stdio.h>#include<signal.h>#include<unistd.h> #include<stdlib.h>void waiting(),stop(),alarming();int wait_mark;main()int p1,p2;if(p1=fork() /*創(chuàng)建子進(jìn)程p1*/if(p2=fork() /*創(chuàng)建子進(jìn)程p2*/ /

3、父進(jìn)程wait_mark=1;signal(SIGINT,stop); /*接收到c信號(hào),轉(zhuǎn)stop*/signal(SIGALRM,alarming);/*接受SIGALRM*/waiting();kill(p1,16); /*向p1發(fā)軟中斷信號(hào)16*/ kill(p2,17); /*向p2發(fā)軟中斷信號(hào)17*/ wait(0); /*同步*/wait(0);printf("parent process is killed!n");exit(0); /會(huì)暫時(shí)停止目前進(jìn)程的執(zhí)行,直到有信號(hào)來(lái)到或子進(jìn)程結(jié)束。 else wait_mark=1;signal(17,stop);s

4、ignal(SIGINT,SIG_IGN); /*忽略 c信號(hào)*/while (wait_mark!=0);lockf(1,1,0);printf("child process2 is killed by parent!n");lockf(1,0,0);exit(0);elsewait_mark=1;signal(16,stop);signal(SIGINT,SIG_IGN); /*忽略c信號(hào)*/while (wait_mark!=0);lockf(1,1,0);printf("child process1 is killed by parent!n")

5、;lockf(1,0,0);exit(0);void waiting()sleep(5);if (wait_mark!=0) kill(getpid(),SIGALRM);void alarming()wait_mark=0;void stop()wait_mark=0;(2)修改上面的程序增加語(yǔ)句signal(SIGINT,SIG_IGN)和語(yǔ)句signal(SIGQUIT,SIG_IGN),再觀察程序執(zhí)行時(shí)屏幕上出現(xiàn)的現(xiàn)象,并分析其原因。這里,signal(SIGINT,SIG_IGN)和signal(SIGQUIT,SIG_IGN)分別為忽略鍵信號(hào)以及忽略中斷信號(hào)。<程序>#

6、include<stdio.h>#include<signal.h>#include<unistd.h>int pid1,pid2;int EndFlag=0;int pf1=0;int pf2=0;void IntDelete()kill(pid1,16);kill(pid2,17);void Int1()printf("child process 1 is killed !by parentn");exit(0);void Int2()printf("child process 2 is killed !by parentn

7、");exit(0);main()int exitpid;if(pid1=fork() if(pid2=fork() signal(SIGINT,IntDelete);waitpid(-1,&exitpid,0);waitpid(-1,&exitpid,0);printf("parent process is killedn");exit(0); else signal(SIGINT,SIG_IGN);signal(17,Int2);pause(); elsesignal(SIGINT,SIG_IGN);signal(16,Int1);pause(

8、);(3)(選做)編制一段程序,實(shí)現(xiàn)進(jìn)程的管道通信。使用pipe()建立一條管道線。兩個(gè)子進(jìn)程p1和p2分別向管道各寫(xiě)一句話: Child 1 is sending message! Child 2 is sending message!而父進(jìn)程則從管道中讀出來(lái)自于兩個(gè)子進(jìn)程的信息,顯示在屏幕上。程序#include <unistd.h>#include <signal.h>#include <stdio.h>int pid1,pid2; main( ) int fd2;char outpipe100,inpipe100;pipe(fd); /*創(chuàng)建一個(gè)管道

9、*/while (pid1=fork( )=-1);if(pid1=0) lockf(fd1,1,0); sprintf(outpipe,"child 1 process is sending message!"); /*把串放入數(shù)組outpipe中*/ write(fd1,outpipe,50); /*向管道寫(xiě)長(zhǎng)為50字節(jié)的串*/ sleep(5); /*自我阻塞5秒*/ lockf(fd1,0,0); exit(0); else while(pid2=fork( )=-1); if(pid2=0) lockf(fd1,1,0); /*互斥*/ sprintf(outpi

10、pe,"child 2 process is sending message!"); write(fd1,outpipe,50); sleep(5); lockf(fd1,0,0); exit(0); else wait(0); /*同步*/ read(fd0,inpipe,50); /*從管道中讀長(zhǎng)為50字節(jié)的串*/ printf("%sn",inpipe); wait(0); read(fd0,inpipe,50); printf("%sn",inpipe); exit(0); 運(yùn)行結(jié)果延遲5秒后顯示:child1 process

11、 is sending message! 再延遲5秒:child2 process is sending message!分析請(qǐng)讀者自行完成 。三、實(shí)驗(yàn)指導(dǎo)(一)信號(hào)1、信號(hào)的基本概念每個(gè)信號(hào)都對(duì)應(yīng)一個(gè)正整數(shù)常量(稱為signal number,即信號(hào)編號(hào),定義在系統(tǒng)頭文件<signal.h>中),代表同一用戶的諸進(jìn)程之間傳送事先約定的信息的類型,用于通知某進(jìn)程發(fā)生了某異常事件。每個(gè)進(jìn)程在運(yùn)行時(shí),都要通過(guò)信號(hào)機(jī)制來(lái)檢查是否有信號(hào)到達(dá)。若有,便中斷正在執(zhí)行的程序,轉(zhuǎn)向與該信號(hào)相對(duì)應(yīng)的處理程序,以完成對(duì)該事件的處理;處理結(jié)束后再返回到原來(lái)的斷點(diǎn)繼續(xù)執(zhí)行。實(shí)質(zhì)上,信號(hào)機(jī)制是對(duì)中斷機(jī)制的一

12、種模擬,故在早期的UNIX版本中又把它稱為軟中斷。信號(hào)與中斷的相似點(diǎn):(1)采用了相同的異步通信方式;(2)當(dāng)檢測(cè)出有信號(hào)或中斷請(qǐng)求時(shí),都暫停正在執(zhí)行的程序而轉(zhuǎn)去執(zhí)行相應(yīng)的處理程序;(3)都在處理完畢后返回到原來(lái)的斷點(diǎn);(4)對(duì)信號(hào)或中斷都可進(jìn)行屏蔽。信號(hào)與中斷的區(qū)別:(1)中斷有優(yōu)先級(jí),而信號(hào)沒(méi)有優(yōu)先級(jí),所有的信號(hào)都是平等的;(2)信號(hào)處理程序是在用戶態(tài)下運(yùn)行的,而中斷處理程序是在核心態(tài)下運(yùn)行;(3)中斷響應(yīng)是及時(shí)的,而信號(hào)響應(yīng)通常都有較大的時(shí)間延遲。信號(hào)機(jī)制具有以下三方面的功能:(1)發(fā)送信號(hào)。發(fā)送信號(hào)的程序用系統(tǒng)調(diào)用kill( )實(shí)現(xiàn);(2)預(yù)置對(duì)信號(hào)的處理方式。接收信號(hào)的程序用sign

13、al( )來(lái)實(shí)現(xiàn)對(duì)處理方式的預(yù)置;(3)收受信號(hào)的進(jìn)程按事先的規(guī)定完成對(duì)相應(yīng)事件的處理。2、信號(hào)的發(fā)送信號(hào)的發(fā)送,是指由發(fā)送進(jìn)程把信號(hào)送到指定進(jìn)程的信號(hào)域的某一位上。如果目標(biāo)進(jìn)程正在一個(gè)可被中斷的優(yōu)先級(jí)上睡眠,核心便將它喚醒,發(fā)送進(jìn)程就此結(jié)束。一個(gè)進(jìn)程可能在其信號(hào)域中有多個(gè)位被置位,代表有多種類型的信號(hào)到達(dá),但對(duì)于一類信號(hào),進(jìn)程卻只能記住其中的某一個(gè)。進(jìn)程用kill( )向一個(gè)進(jìn)程或一組進(jìn)程發(fā)送一個(gè)信號(hào)。3、對(duì)信號(hào)的處理當(dāng)一個(gè)進(jìn)程要進(jìn)入或退出一個(gè)低優(yōu)先級(jí)睡眠狀態(tài)時(shí),或一個(gè)進(jìn)程即將從核心態(tài)返回用戶態(tài)時(shí),核心都要檢查該進(jìn)程是否已收到軟中斷。當(dāng)進(jìn)程處于核心態(tài)時(shí),即使收到軟中斷也不予理睬;只有當(dāng)它返回

14、到用戶態(tài)后,才處理軟中斷信號(hào)。對(duì)軟中斷信號(hào)的處理分三種情況進(jìn)行:(1)如果進(jìn)程收到的軟中斷是一個(gè)已決定要忽略的信號(hào)(function=1),進(jìn)程不做任何處理便立即返回;(2)進(jìn)程收到軟中斷后便退出(function=0);(3)執(zhí)行用戶設(shè)置的軟中斷處理程序。(二)所涉及的中斷調(diào)用1、kill( ) 功能描述:用于向任何進(jìn)程組或進(jìn)程發(fā)送信號(hào)。系統(tǒng)調(diào)用格式 int kill(pid,sig)參數(shù)定義 int pid,sig;其中,pid是一個(gè)或一組進(jìn)程的標(biāo)識(shí)符,參數(shù)sig是要發(fā)送的軟中斷信號(hào)。(1)pid>0時(shí),核心將信號(hào)發(fā)送給進(jìn)程pid。(2)pid=0時(shí),核心將信號(hào)發(fā)送給與發(fā)送進(jìn)程同組的

15、所有進(jìn)程。(3)pid=-1時(shí),核心將信號(hào)發(fā)送給所有用戶標(biāo)識(shí)符真正等于發(fā)送進(jìn)程的有效用戶標(biāo)識(shí)號(hào)的進(jìn)程。2、signal( )功能描述:預(yù)置對(duì)信號(hào)的處理方式,允許調(diào)用進(jìn)程控制軟中斷信號(hào)。系統(tǒng)調(diào)用格式 signal(sig,function)頭文件為 #include <signal.h>參數(shù)定義int sig;void (*func) ( )其中sig用于指定信號(hào)的類型,sig為0則表示沒(méi)有收到任何信號(hào),余者如下表:值 名 字 說(shuō) 明01 SIGHUP 掛起(hangup)02 SIGINT 中斷,當(dāng)用戶從鍵盤(pán)按c鍵或break鍵時(shí)03 SIGQUIT 退出,當(dāng)用戶從鍵盤(pán)按quit鍵

16、時(shí)04 SIGILL 非法指令05 SIGTRAP 跟蹤陷阱(trace trap),啟動(dòng)進(jìn)程,跟蹤代碼的執(zhí)行06 SIGIOT IOT 指令07 SIGEMT EMT指令08 SIGFPE 浮點(diǎn)運(yùn)算溢出09 SIGKILL 殺死、終止進(jìn)程 10 SIGBUS 總線錯(cuò)誤11 SIGSEGV 段違例(segmentation violation),進(jìn)程試圖去訪問(wèn)其虛地址空間以外的位置12 SIGSYS 系統(tǒng)調(diào)用中參數(shù)錯(cuò),如系統(tǒng)調(diào)用號(hào)非法13 SIGPIPE 向某個(gè)非讀管道中寫(xiě)入數(shù)據(jù)14SIGALRM 鬧鐘。當(dāng)某進(jìn)程希望在某時(shí)間后接收信號(hào)時(shí)發(fā)此信號(hào)15 SIGTERM 軟件終止(software

17、termination)16 SIGUSR1 用戶自定義信號(hào)117 SIGUSR2 用戶自定義信號(hào)218 SIGCLD 某個(gè)子進(jìn)程死19 SIGPWR 電源故障 function:在該進(jìn)程中的一個(gè)函數(shù)地址,在核心返回用戶態(tài)時(shí),它以軟中斷信號(hào)的序號(hào)作為參數(shù)調(diào)用該函數(shù),對(duì)除了信號(hào)SIGKILL,SIGTRAP和SIGPWR以外的信號(hào),核心自動(dòng)地重新設(shè)置軟中斷信號(hào)處理程序的值為SIG_DFL,一個(gè)進(jìn)程不能捕獲SIGKILL信號(hào)。function 的解釋如下:(1)function=1時(shí),進(jìn)程對(duì)sig類信號(hào)不予理睬,亦即屏蔽了該類信號(hào);(2)function=0時(shí),缺省值,進(jìn)程在收到sig信號(hào)后應(yīng)終止

18、自己;(3)function為非0,非1類整數(shù)時(shí),function的值即作為信號(hào)處理程序的指針。(三)實(shí)驗(yàn)(1)的參考<程序流程圖>程序#include<stdio.h>#include<signal.h>#include<unistd.h> void waiting(),stop(),alarming();int wait_mark;main()int p1,p2;if(p1=fork() /*創(chuàng)建子進(jìn)程p1*/if(p2=fork() /*創(chuàng)建子進(jìn)程p2*/ /父進(jìn)程wait_mark=1;signal(SIGINT,stop); /*接收到

19、DEL信號(hào),轉(zhuǎn)stop*/signal(SIGALRM,alarming);/*接受SIGALRMwaiting();kill(p1,16); /*向p1發(fā)軟中斷信號(hào)16*/ kill(p2,17); /*向p2發(fā)軟中斷信號(hào)17*/ wait(0); /*同步*/wait(0);printf("parent process is killed!n");exit(0); else wait_mark=1;signal(17,stop);signal(SIGINT,SIG_IGN); /*忽略 c信號(hào)*/while (wait_mark!=0);lockf(1,1,0);pri

20、ntf("child process2 is killed by parent!n");lockf(1,0,0);exit(0);elsewait_mark=1;signal(16,stop);signal(SIGINT,SIG_IGN); /*忽略c信號(hào)*/while (wait_mark!=0);lockf(1,1,0);printf("child process1 is killed by parent!n");lockf(1,0,0);exit(0);void waiting()sleep(5);if (wait_mark!=0) kill(ge

21、tpid(),SIGALRM);void alarming()wait_mark=0;void stop()wait_mark=0;<運(yùn)行結(jié)果> 不做任何操作等待五秒鐘父進(jìn)程會(huì)在子進(jìn)程先退出后再退出,并打印退出的順序;或者點(diǎn)擊ctrl+C后程序退出并打印退出的順序。任務(wù)2在上面的任務(wù)1中,增加語(yǔ)句signal(SIGINT,SIG_IGN)和語(yǔ)句signal(SIGQUIT,SIG_IGN),觀察執(zhí)行結(jié)果,并分析原因。這里,signal(SIGINT,SIG_IGN)和signal(SIGQUIT,SIG_IGN)分別為忽略鍵信號(hào)以及忽略中斷信號(hào)。<程序>#includ

22、e<stdio.h>#include<signal.h>#include<unistd.h>int pid1,pid2;int EndFlag=0;int pf1=0;int pf2=0;void IntDelete()kill(pid1,16);kill(pid2,17);void Int1()printf("child process 1 is killed !by parentn");exit(0);void Int2()printf("child process 2 is killed !by parentn"

23、);exit(0);main()int exitpid;if(pid1=fork() if(pid2=fork() signal(SIGINT,IntDelete);waitpid(-1,&exitpid,0);waitpid(-1,&exitpid,0);printf("parent process is killedn");exit(0); else signal(SIGINT,SIG_IGN);signal(17,Int2);pause(); elsesignal(SIGINT,SIG_IGN);signal(16,Int1);pause();運(yùn)行結(jié)果請(qǐng)讀者將上述程序輸入計(jì)算機(jī)后,執(zhí)行并觀察。1 進(jìn)程的管道通信任務(wù) 編制一段程序,實(shí)現(xiàn)進(jìn)程的管道通信。使用系統(tǒng)調(diào)用pipe()建立一條管道線。兩個(gè)子進(jìn)程p1和p2分別向通道個(gè)寫(xiě)一句話: child1 process is sending message!child2 process is sending message!而父進(jìn)程則從管道中讀出來(lái)自兩個(gè)進(jìn)程的信息,顯示在屏幕上。程序#include <unistd.h&

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 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ì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論