操作系統(tǒng)課程設(shè)計(jì)-信號(hào)機(jī)制實(shí)驗(yàn)_第1頁
已閱讀1頁,還剩9頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡介

1、<p><b>  實(shí)驗(yàn)手冊(cè)內(nèi)容:</b></p><p>  (一) 信號(hào)機(jī)制實(shí)驗(yàn)</p><p><b>  實(shí)驗(yàn)?zāi)康?lt;/b></p><p><b>  1、了解什么是信號(hào)</b></p><p>  2、熟悉LINUX系統(tǒng)中進(jìn)程之間軟中斷通信的基本原理<

2、/p><p><b>  實(shí)驗(yàn)內(nèi)容</b></p><p>  1、編寫程序:用fork( )創(chuàng)建兩個(gè)子進(jìn)程,再用系統(tǒng)調(diào)用signal( )讓父進(jìn)程捕捉鍵盤上來的中斷信號(hào)(即按^c鍵);捕捉到中斷信號(hào)后,父進(jìn)程用系統(tǒng)調(diào)用kill( )向兩個(gè)子進(jìn)程發(fā)出信號(hào),子進(jìn)程捕捉到信號(hào)后分別輸出下列信息后終止:</p><p>  Child process1

3、is killed by parent!</p><p>  Child process2 is killed by parent!</p><p>  父進(jìn)程等待兩個(gè)子進(jìn)程終止后,輸出如下的信息后終止:</p><p>  Parent process is killed!</p><p>  2、分析利用軟中斷通信實(shí)現(xiàn)進(jìn)程同步的機(jī)理<

4、;/p><p><b>  實(shí)驗(yàn)指導(dǎo)</b></p><p><b>  一、信號(hào)</b></p><p><b>  1、信號(hào)的基本概念</b></p><p>  每個(gè)信號(hào)都對(duì)應(yīng)一個(gè)正整數(shù)常量(稱為signal number,即信號(hào)編號(hào)。定義在系統(tǒng)頭文件<signal.

5、h>中),代表同一用戶的諸進(jìn)程之間傳送事先約定的信息的類型,用于通知某進(jìn)程發(fā)生了某異常事件。每個(gè)進(jìn)程在運(yùn)行時(shí),都要通過信號(hào)機(jī)制來檢查是否有信號(hào)到達(dá)。若有,便中斷正在執(zhí)行的程序,轉(zhuǎn)向與該信號(hào)相對(duì)應(yīng)的處理程序,以完成對(duì)該事件的處理;處理結(jié)束后再返回到原來的斷點(diǎn)繼續(xù)執(zhí)行。實(shí)質(zhì)上,信號(hào)機(jī)制是對(duì)中斷機(jī)制的一種模擬,故在早期的UNIX版本中又把它稱為軟中斷。</p><p>  信號(hào)與中斷的相似點(diǎn):</p>

6、<p>  (1)采用了相同的異步通信方式;</p><p> ?。?)當(dāng)檢測出有信號(hào)或中斷請(qǐng)求時(shí),都暫停正在執(zhí)行的程序而轉(zhuǎn)去執(zhí)行相應(yīng)的處理程序;</p><p>  (3)都在處理完畢后返回到原來的斷點(diǎn);</p><p>  (4)對(duì)信號(hào)或中斷都可進(jìn)行屏蔽。</p><p><b>  信號(hào)與中斷的區(qū)別:</b

7、></p><p> ?。?)中斷有優(yōu)先級(jí),而信號(hào)沒有優(yōu)先級(jí),所有的信號(hào)都是平等的;</p><p> ?。?)信號(hào)處理程序是在用戶態(tài)下運(yùn)行的,而中斷處理程序是在核心態(tài)下運(yùn)行;</p><p>  (3)中斷響應(yīng)是及時(shí)的,而信號(hào)響應(yīng)通常都有較大的時(shí)間延遲。</p><p>  信號(hào)機(jī)制具有以下三方面的功能:</p><

8、;p> ?。?)發(fā)送信號(hào)。發(fā)送信號(hào)的程序用系統(tǒng)調(diào)用kill( )實(shí)現(xiàn);</p><p> ?。?)預(yù)置對(duì)信號(hào)的處理方式。接收信號(hào)的程序用signal( )來實(shí)現(xiàn)對(duì)處理方式的預(yù)置;</p><p> ?。?)收受信號(hào)的進(jìn)程按事先的規(guī)定完成對(duì)相應(yīng)事件的處理。</p><p><b>  2、信號(hào)的發(fā)送</b></p><p

9、>  信號(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è)。</p><p>  進(jìn)程用kill( )向一個(gè)進(jìn)程或一組進(jìn)程發(fā)送一個(gè)信號(hào)。</p><p><b>  3、對(duì)信號(hào)的

10、處理</b></p><p>  當(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)它返回到用戶態(tài)后,才處理軟中斷信號(hào)。對(duì)軟中斷信號(hào)的處理分三種情況進(jìn)行:</p><p> ?。?)如果進(jìn)程收到的軟中斷是一個(gè)已決定要忽略的信號(hào)(function=1),進(jìn)程不做

11、任何處理便立即返回;</p><p>  (2)進(jìn)程收到軟中斷后便退出(function=0);</p><p> ?。?)執(zhí)行用戶設(shè)置的軟中斷處理程序。</p><p>  二、所涉及的中斷調(diào)用</p><p><b>  1、kill( )</b></p><p><b>  系統(tǒng)調(diào)

12、用格式</b></p><p>  int kill(pid,sig)</p><p><b>  參數(shù)定義</b></p><p>  int pid,sig;</p><p>  其中,pid是一個(gè)或一組進(jìn)程的標(biāo)識(shí)符,參數(shù)sig是要發(fā)送的軟中斷信號(hào)。</p><p> ?。?)

13、pid>0時(shí),核心將信號(hào)發(fā)送給進(jìn)程pid。</p><p> ?。?)pid=0時(shí),核心將信號(hào)發(fā)送給與發(fā)送進(jìn)程同組的所有進(jìn)程。</p><p> ?。?)pid=-1時(shí),核心將信號(hào)發(fā)送給所有用戶標(biāo)識(shí)符真正等于發(fā)送進(jìn)程的有效用戶標(biāo)識(shí)號(hào)的進(jìn)程。</p><p>  2、signal( )</p><p>  預(yù)置對(duì)信號(hào)的處理方式,允許調(diào)用進(jìn)

14、程控制軟中斷信號(hào)。</p><p><b>  系統(tǒng)調(diào)用格式</b></p><p>  signal(sig,function)</p><p><b>  頭文件為</b></p><p>  #include <signal.h></p><p><b

15、>  參數(shù)定義</b></p><p>  signal(sig,function)</p><p><b>  int sig;</b></p><p>  void (*func) ( )</p><p>  其中sig用于指定信號(hào)的類型,sig為0則表示沒有收到任何信號(hào),余者如下表:</p

16、><p>  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(進(jìn)程終止),一個(gè)進(jìn)程不能捕獲SIGKILL信號(hào)。</p><p>  function 的解釋如下:</p><p> ?。?)f

17、unction=1(即SIG_IGN)時(shí),進(jìn)程對(duì)sig類信號(hào)不予理睬,亦即屏蔽了該類信號(hào);</p><p> ?。?)function=0(即SIG_DFL)時(shí),缺省值,進(jìn)程在收到sig信號(hào)后應(yīng)終止自己;</p><p>  (3)function為非0、非1類整數(shù)時(shí),function的值即作為信號(hào)處理程序的指針。</p><p><b>  三、參考程序

18、</b></p><p>  #include <stdio.h></p><p>  #include <signal.h></p><p>  #include <unistd.h></p><p>  void waiting( ),stop( );</p><p>

19、;  int wait_mark;</p><p><b>  main( )</b></p><p><b>  {</b></p><p>  int p1,p2,stdout;</p><p>  while((p1=fork( ))= =-1); /*創(chuàng)建子進(jìn)程p1*/</

20、p><p><b>  if (p1>0)</b></p><p><b>  {</b></p><p>  while((p2=fork( ))= =-1); /*創(chuàng)建子進(jìn)程p2*/</p><p><b>  if(p2>0)</b></p>

21、<p><b>  {</b></p><p>  wait_mark=1;</p><p>  signal(SIGINT,stop); /*接收到^c信號(hào),轉(zhuǎn)stop*/</p><p>  waiting( );</p><p>  kill(p1,16); /*向p1發(fā)軟中斷信號(hào)16

22、*/</p><p>  kill(p2,17); /*向p2發(fā)軟中斷信號(hào)17*/</p><p>  wait(0); /*同步*/</p><p><b>  wait(0);</b></p><p>  printf("Parent process is killed!\

23、n");</p><p><b>  exit(0);</b></p><p><b>  }</b></p><p><b>  else</b></p><p><b>  {</b></p><p>  wait_m

24、ark=1;</p><p>  signal(17,stop); /*接收到軟中斷信號(hào)17,轉(zhuǎn)stop*/</p><p>  waiting( );</p><p>  lockf(stdout,1,0);</p><p>  printf("Child process 2 is killed by parent!\n&qu

25、ot;);</p><p>  lockf(stdout,0,0);</p><p><b>  exit(0);</b></p><p><b>  }</b></p><p><b>  }</b></p><p><b>  else&l

26、t;/b></p><p><b>  {</b></p><p>  wait_mark=1;</p><p>  signal(16,stop); /*接收到軟中斷信號(hào)16,轉(zhuǎn)stop*/</p><p>  waiting( );</p><p>  lockf(stdo

27、ut,1,0);</p><p>  printf("Child process 1 is killed by parent!\n");</p><p>  lockf(stdout,0,0);</p><p><b>  exit(0);</b></p><p><b>  }

28、}</b></p><p>  void waiting( )</p><p><b>  {</b></p><p>  while(wait_mark!=0);</p><p><b>  }</b></p><p>  void stop( )</p&

29、gt;<p><b>  {</b></p><p>  wait_mark=0;</p><p><b>  }</b></p><p><b>  四、運(yùn)行結(jié)果</b></p><p>  屏幕上無反應(yīng),按下^C后,顯示 Parent process i

30、s killed!</p><p><b>  五、分析原因</b></p><p>  上述程序中,signal( )都放在一段程序的前面部位,而不是在其他接收信號(hào)處。這是因?yàn)閟ignal( )的執(zhí)行只是為進(jìn)程指定信號(hào)值16或17的作用,以及分配相應(yīng)的與stop( )過程鏈接的指針。因而,signal( )函數(shù)必須在程序前面部分執(zhí)行。</p><

31、;p>  本方法通信效率低,當(dāng)通信數(shù)據(jù)量較大時(shí)一般不用此法。</p><p><b>  六、思考</b></p><p>  1、該程序段前面部分用了兩個(gè)wait(0),它們起什么作用?</p><p>  2、該程序段中每個(gè)進(jìn)程退出時(shí)都用了語句exit(0),為什么?</p><p>  3、為何預(yù)期的結(jié)果并未

32、顯示出?</p><p>  4、(重點(diǎn))程序該如何修改才能得到正確結(jié)果?(實(shí)驗(yàn)報(bào)告中寫出完整程序)</p><p>  5、*不修改程序如何得到期望的輸出?(給出合理的思路即可)</p><p>  以下為實(shí)驗(yàn)報(bào)告部分:</p><p><b>  實(shí)驗(yàn) 信號(hào)機(jī)制</b></p><p>  

33、姓名 Lee QQ 615824191</p><p><b>  實(shí)驗(yàn)?zāi)康?lt;/b></p><p><b>  1、了解什么是信號(hào)</b></p><p>  2、熟悉LINUX系統(tǒng)中進(jìn)程之間軟中斷通信的基本原理</p><p><b>  實(shí)驗(yàn)內(nèi)容</b></p&g

34、t;<p>  1、編寫程序:用fork( )創(chuàng)建兩個(gè)子進(jìn)程,再用系統(tǒng)調(diào)用signal( )讓父進(jìn)程捕捉鍵盤上來的中斷信號(hào)(即按^c鍵);捕捉到中斷信號(hào)后,父進(jìn)程用系統(tǒng)調(diào)用kill( )向兩個(gè)子進(jìn)程發(fā)出信號(hào),子進(jìn)程捕捉到信號(hào)后分別輸出下列信息后終止:</p><p>  Child process1 is killed by parent!</p><p>  Child p

35、rocess2 is killed by parent!</p><p>  父進(jìn)程等待兩個(gè)子進(jìn)程終止后,輸出如下的信息后終止:</p><p>  Parent process is killed!</p><p>  2、分析利用軟中斷通信實(shí)現(xiàn)進(jìn)程同步的機(jī)理</p><p><b>  實(shí)驗(yàn)步驟</b></p&

36、gt;<p>  將參考程序用vi編輯器錄入,然后編譯執(zhí)行</p><p>  #include <stdio.h></p><p>  #include <signal.h></p><p>  #include <unistd.h></p><p>  void waiting( ),st

37、op( );</p><p>  int wait_mark;</p><p><b>  main( )</b></p><p><b>  {</b></p><p>  int p1,p2,stdout;</p><p>  while((p1=fork( ))= =-

38、1); /*創(chuàng)建子進(jìn)程p1*/</p><p><b>  if (p1>0)</b></p><p><b>  {</b></p><p>  while((p2=fork( ))= =-1); /*創(chuàng)建子進(jìn)程p2*/</p><p><b>  if(p2&

39、gt;0)</b></p><p><b>  {</b></p><p>  wait_mark=1;</p><p>  signal(SIGINT,stop); /*接收到^c信號(hào),轉(zhuǎn)stop*/</p><p>  waiting( );</p><p>  kill(p1

40、,16); /*向p1發(fā)軟中斷信號(hào)16*/</p><p>  kill(p2,17); /*向p2發(fā)軟中斷信號(hào)17*/</p><p>  wait(0); /*同步*/</p><p><b>  wait(0);</b></p><p>  printf("

41、Parent process is killed!\n");</p><p><b>  exit(0);</b></p><p><b>  }</b></p><p><b>  else</b></p><p><b>  {</b><

42、;/p><p>  wait_mark=1;</p><p>  signal(17,stop); /*接收到軟中斷信號(hào)17,轉(zhuǎn)stop*/</p><p>  waiting( );</p><p>  lockf(stdout,1,0);</p><p>  printf("Child process 2

43、 is killed by parent!\n");</p><p>  lockf(stdout,0,0);</p><p><b>  exit(0);</b></p><p><b>  }</b></p><p><b>  }</b></p>

44、<p><b>  else</b></p><p><b>  {</b></p><p>  wait_mark=1;</p><p>  signal(16,stop); /*接收到軟中斷信號(hào)16,轉(zhuǎn)stop*/</p><p>  waiting( );</p&

45、gt;<p>  lockf(stdout,1,0);</p><p>  printf("Child process 1 is killed by parent!\n");</p><p>  lockf(stdout,0,0);</p><p><b>  exit(0);</b></p>&

46、lt;p><b>  } }</b></p><p>  void waiting( )</p><p><b>  {</b></p><p>  while(wait_mark!=0);</p><p><b>  }</b></p><

47、p>  void stop( )</p><p><b>  {</b></p><p>  wait_mark=0;</p><p><b>  }</b></p><p><b>  運(yùn)行結(jié)果</b></p><p>  屏幕上無反應(yīng),按下^C

48、后,顯示 Parent process is killed!</p><p><b>  分析原因</b></p><p>  上述程序中,signal( )都放在一段程序的前面部位,而不是在其他接收信號(hào)處。這是因?yàn)閟ignal( )的執(zhí)行只是為進(jìn)程指定信號(hào)值16或17的作用,以及分配相應(yīng)的與stop( )過程鏈接的指針。因而,signal( )函數(shù)必須在程序

49、前面部分執(zhí)行。</p><p><b>  思考</b></p><p>  1. 該程序段前面部分用了兩個(gè)wait(0),它們起什么作用?</p><p>  該程序段前面部分用的兩個(gè) wait(0) 是為了讓父進(jìn)程等待子進(jìn)程結(jié)束后再結(jié)束自己,在此過程中,父進(jìn)程處于掛起狀態(tài)。</p><p>  2. 該程序段中每個(gè)進(jìn)

50、程退出時(shí)都用了語句exit(0),為什么?</p><p>  用 exit(0) 是為了讓子進(jìn)程自我終止,正常退出。</p><p>  3. 為何預(yù)期的結(jié)果并未顯示出?</p><p>  p1、p2 都會(huì)捕捉該中斷信號(hào)。對(duì)于父進(jìn)程,當(dāng)它捕捉到中斷信號(hào)后就會(huì)就會(huì)轉(zhuǎn)向程序中指定的函數(shù)“stop()”,當(dāng)“stop()”執(zhí)行完畢后,父進(jìn)程被喚醒,從中斷處繼續(xù)運(yùn)行。對(duì)

51、于子進(jìn)程,由于沒有給它們指定收到中斷信號(hào)后的動(dòng)作,它們會(huì)在捕捉到中斷信號(hào)后執(zhí)行默認(rèn)操作,即結(jié)束自己。所以當(dāng)我們發(fā)出中斷信號(hào)后,父進(jìn)程按預(yù)計(jì)方式正常執(zhí)行,而 p1、p2 就被自己結(jié)束了,從而也就不會(huì)有預(yù)計(jì)的結(jié)果了。</p><p>  4. 程序該如何修改才能得到正確結(jié)果?</p><p>  為了使程序運(yùn)行得到正確的結(jié)果,可以在每個(gè)子進(jìn)程程序段開頭加上忽略“^C”中斷信號(hào)的語句,即:sig

52、nal(SIGINT,SIG_IGN) 。</p><p>  #include <stdio.h></p><p>  #include <signal.h></p><p>  #include <unistd.h></p><p>  #include <stdlib.h></p&g

53、t;<p>  void waiting() ;</p><p>  void stop() ;</p><p>  int wait_mark ;</p><p><b>  main() {</b></p><p>  int p1,p2,stdout ;</p><p>  w

54、hile((p1 = fork()) == -1) ;</p><p>  if (p1 > 0) {</p><p>  while((p2 = fork()) == -1) ;</p><p>  if (p2 > 0) {</p><p>  wait_mark = 1 ;</p><p>  sig

55、nal(SIGINT,stop) ;</p><p>  waiting() ;</p><p>  kill(p1,16) ;</p><p>  kill(p2,17) ;</p><p><b>  wait(0) ;</b></p><p><b>  wait(0) ;<

56、/b></p><p>  printf("Parent process is killed !\n") ;</p><p><b>  exit(0) ;</b></p><p><b>  } else {</b></p><p>  signal(SIGINT,SIG

57、_IGN) ;</p><p>  wait_mark = 1 ;</p><p>  signal(17,stop) ;</p><p>  waiting() ;</p><p>  lockf(stdout,1,0) ;</p><p>  printf("Child process 2 is kill

58、ed by parent !\n") ;</p><p>  lockf(stdout,0,0) ;</p><p><b>  exit(0) ;</b></p><p><b>  }</b></p><p><b>  } else {</b></p>

59、;<p>  signal(SIGINT,SIG_IGN) ;</p><p>  wait_mark = 1 ;</p><p>  signal(16,stop) ;</p><p>  waiting() ;</p><p>  lockf(stdout,1,0) ;</p><p>  print

60、f("Child process 1 is killed by parent !\n") ;</p><p>  lockf(stdout,0,0) ;</p><p><b>  exit(0) ;</b></p><p><b>  }</b></p><p><b&g

61、t;  }</b></p><p>  void waiting() {</p><p>  while(wait_mark != 0) ;</p><p><b>  }</b></p><p>  void stop() {</p><p>  wait_mark = 0 ;<

62、;/p><p><b>  }</b></p><p>  不修改程序如何得到期望的輸出?</p><p>  在不修改程序的情況下要輸出期望的結(jié)果,可以單獨(dú)向父進(jìn)程發(fā)送SIGINT信號(hào),這樣即可避免子進(jìn)程由于收到SIGINT信號(hào)執(zhí)行默認(rèn)操作而自我終止,具體實(shí)現(xiàn)方法:</p><p> ?。ㄔ搶?shí)驗(yàn)中程序名為:demo2)&l

63、t;/p><p>  首先讓程序在后臺(tái)運(yùn)行,命令:./demo2&</p><p>  執(zhí)行該命令后,會(huì)在后臺(tái)生成3個(gè)進(jìn)程,使用ps命令可以查看到它們的PID (相對(duì)小的PID應(yīng)該為父進(jìn)程的PID,原因是創(chuàng)建時(shí)間相對(duì)早)。</p><p>  然后向后臺(tái)的父進(jìn)程發(fā)送SIGINT信號(hào),命令:kill –SIGINT 28664 (其中28664為父進(jìn)程的PID)&

64、lt;/p><p>  具體實(shí)驗(yàn)結(jié)果見下圖:</p><p><b>  心得與體會(huì)</b></p><p>  通過該實(shí)驗(yàn),我對(duì) UNIX/LINUX 下軟中斷的實(shí)現(xiàn)原理與機(jī)制有了一個(gè)初步的認(rèn)識(shí),可以用kill() 函數(shù)和signal() 函數(shù)實(shí)現(xiàn)簡單的軟中斷程序,并且領(lǐng)會(huì)到了程序中wait_mark 所起的作用。在研究第五個(gè)思考題時(shí),學(xué)習(xí)了進(jìn)程

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 眾賞文庫僅提供信息存儲(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)論