實驗二 進程式控制制
實驗目的:
(1)理解進程的同步、互斥、撤消等控制方法
(2)熟悉進程間通過非強制中斷傳遞控制資訊的方法(低級通訊)
實驗儀器及材料:
微電腦、紅帽子Linux系統
實驗內容:
任務1:並發進程間通過非強制中斷傳遞控制訊號,實現進程同步
#include<stdio.h>
#include<signal.h>
#include<unistd.h>
intwait_mark;
voidwaiting( ),stop( );
main( ){
intp1,p2;
while((p1=fork())==-1);
if (p1>0) { /*主進程的處理*/
while ((p2=fork())==-1);
if (p2>0) { /*主進程的處理*/
wait_mark=1;
signal(SIGINT,stop);/*預設對SIGINT訊號的處理過程*/
waiting();/*等待接收ctrl+c訊號*/
kill(p1,16);/*向p1發出訊號16*/
kill(p2,17);/*向p2發出訊號17*/
wait(0);/*同步*/
wait(0);
print(“parents is killed\n”);
exit(0);
}
else { /*p2進程的處理*/
wait_mark=1;
signal(17,stop); /*預設對17訊號的處理過程*/
signal(2,1);/*忽略ctrl+c*/
waiting();/*等待訊號17*/
lockf(stdout,1,0);/*用上鎖的方法實現互斥*/
printf(“P2 iskilled by parent\n”);
lockf(stdout,0,0);
/*類比P2被kill時進程的工作*/
exit(0);/*P2正常結束*/
}
}
else { /*p1進程的處理*/
wait_mark=1;
signal(16,stop);
signal(2,1);
waiting();/*等待訊號16*/
lockf(stdout,1,0); /*用上鎖的方法實現互斥*/
printf(“P1 iskilled by parent\n”);
lockf(stdout,0,0);
/*類比P1被kill時進程的工作*/
exit(0); /*P1正常結束*/
}
}
voidwaiting()
{
while(wait_mark!=0);
}
voidstop()
{
wait_mark=0;
}
運行程式,觀察運行結果,並分析。
涉及到的系統調用:
1、wait( )
等待子進程運行結束。如果子進程沒有完成,父進程一直等待。wait( )將調用進程掛起,直至其子進程因暫停或終止而發來非強制中斷訊號將其喚醒為止。如果在wait( )前已有子進程暫停或終止,則調用進程做適當處理後便返回。
系統調用格式:
int wait(status)
int *status;
其中,status是使用者空間的地址。它的低8位反應子進程狀態,為0表示子進程正常結束,非0則表示出現了各種各樣的問題;高8位則帶回了exit( )的傳回值。exit()傳回值由系統給出。
2、exit( )
終止本進程的執行。
系統調用格式:
void exit(status)
intstatus;
其中,status是返回給父進程的一個整數,以備查考。
為了及時回收進程所佔用的資源並減少父進程的幹預,UNIX/LINUX利用exit( )來實現進程的自我終止,通常父進程在建立子進程時,應在子進程的末尾安排一條exit(),使子進程自我終止。exit(0)表示進程正常終止,exit(1)表示進程運行有錯,異常終止。
如果調用進程在執行exit( )時,其父進程正在等待它的終止,則父進程可立即得到其返回的整數。
3、lockf( )
用作鎖定檔案的某些段或者整個檔案。
本函數的標頭檔為:
#include "unistd.h"
系統調用格式:
int lockf(files,function,size)
int files,function;
long size;
其中:files是檔案描述符;function是鎖定和解鎖:1表示鎖定,0表示解鎖。size是鎖定或解鎖的位元組數,若為0,表示從檔案的當前位置到檔案尾。
4、kill( )
向一個或一組進程發送一個非強制中斷訊號。
系統調用格式:
int kill(pid,sig)
int pid,sig;
其中,pid是一個或一組進程的標識符,參數sig是要發送的非強制中斷訊號。
(1)pid>0時,核心會將訊號發送給進程pid。
(2)pid=0時,核心會將訊號發送給與發送進程同組的所有進程。
(3)pid=-1時,核心會將訊號發送給所有使用者識別碼真正等於發送進程的有效使用者標識號的進程。
5、signal( )
預置對訊號的處理方式,允許調用進程式控制制非強制中斷訊號。
本函數的標頭檔為:
#include <signal.h>
系統調用格式:
signal(sig,function)
int sig;
void (*func) ( )
其中sig用於指定訊號的類型,sig為0則表示沒有收到任何訊號。function是該進程中的一個函數地址,function 的解釋如下:
(1)function=1時,進程對sig類訊號不予理睬,亦即屏蔽了該類訊號;
(2)function=0時,預設值,進程在收到sig訊號後應終止自己;
(3)function為非0、非1整數時,function的值即作為訊號處理常式的指標。
思考:
1 在本程式中,進程的同步和互斥是如何?的?
2 在本實驗程式中調用lockf(),參數stdout指的是什嗎?
3 將子進程P1、P2的程式段改為2個獨立的函數,設計好後給父進程調用,程式應該如何改寫?(實驗報告上給出完整的源碼,並在機器上運行。)
Stty –a ;在linux下顯示鍵盤的“鍵”與其輸入訊號的對應關係。