1、进程软中断通信 集团文件版本号:(M928-T898-M248-WU2669-I2896-DQ586-M1988)进程软中断通信进程软中断通信【预备知识】进程软中断通信涉及的系统调用描述如下。1kill()进程用kill()向一个进程或一组进程发送一个信号。系统调用格式为int kill(pid,sig)。其中,pid是一个或一组进程的标识符,sig是要发送的软中断信号。信号的发送分如下三种情况。pid0时,核心将信号发送给进程pid。pid=0时,核心将信号发送给与发送进程同组的所用进程。pid=-1时,核心将信号发送给所有用户标识符真正等于发送进程的有效用户标识号的进程。2.signal(
2、sig,function)接收信号的程序用signal()来实现对处理方式的预置,允许调用进程控制软中断信号。系统调用格式为signal(sig function),此时需包含头文件signal.h。其中,sig用于指定信号的类型,sig为0则表示没有收到任何信号,其余类型如表所示。调用函数使用如下头文件:#include参数定义如下:signal (sig,function)int sig;void(*func) (); function是该进程中的一个函数地址,在核心返回用户态时,它以软中断信号的序号作为参数调用该函数,对除了信号SIGKILL、SIGTRAP和SIGPWR以外的信号,核心
3、自动重新设置软中断信号处理程序的值为SIG_DFL,进程不能捕获SIGKILL信号。function的解释如下:(1)function=1时,进程对sig类信号不做任何处理便立即返回,亦即屏蔽该类型号。(2)function=0时,默认值,进程收到sig信号后终止自己。(3)function为非0、非1类整数时,执行用户设置的软中断处理程序。信号的类型值名字说明01SIGHUP挂起(hangup)02SIGINT中断,当用户从键盘按“c”键或“break”键时03SIGQUIT退出,当用户从键盘按“quit“键时04SIGILL非法指令05SIGTRAP跟踪陷阱(trace trap)06SI
4、GIOTIOT指令07SIGEMTEMT指令08SIGFPE浮点运算溢出09SIGKILL终止进程10SIGBUS总线错误11SIGSEGV段违例,进程试图去访问其虚地址空间以外的位置12SIGSYS系统调用中参数错,如系统调用号非法13SIGPIPE向某个非读管道中写入数据14SIGALRM闹钟。当进程希望在某时间后接收信号时发此信号15SIGTERM软件终止(software termination)16SIGUSR1用户自定义信号117SIGUSR2用户自定义信号218SIGCLD某个子进程死19SIGPWR电源故障编程实现例【任务】编程实现,父进程生成子进程,父进程发送信号并等待,子进
5、程接收信号并完成某种功能,然后自我终止并唤醒父进程。【程序】#include #include #include int func();main() int i,j;signal(17,func);if(i=fork() printf(“Parent: Signal 17 will be send t to Child! n ”)kill(i,17);wait(0);printf (“Parent: finished! n”);elsesleep(10);printf(“Child: A signal from my Parent is received ! n”);exit();func()
6、printf(“It is signal 17 processing function ! n”)【运行结果】【分析】编程实现例【任务】编制一程,使用系统调用fork()创建两个子进程,再用系统调用signal()让父进程捕捉键盘上来的中断信号(即DEL键),当捕捉到中断信号后,父进程用系统调用kill()向两个子进程发出信号,子进程捕捉到信号后,分别输出下列信息后终止。child process 1 is killed by parent!child process 2 is killed by parent!父进程等待两个子进程终止后,输出以下信息后终止。Parent process is
7、 killed!【程序】#include #include #include int waiting(),stop();int wait_mark;main() int p1,p2;while (p1=fork()=-1);if (p10) while (p2=fork()=-1); if (p20) printf(“parentn”); wait_mark=1; signal(SIGINT,stop); /*接收DEL信号,并转stop()*/ waiting(); kill(p1,16); /*向P1发中断信号16*/ kill(p2,17); /*向P2发中断信号17*/ wait(0)
8、; wait(0); printf(“parent process is killed!n”); exit(0) else printf(“p2n”); wait_mark=1; signal(17,stop) waiting(); lockf(stdout,1,0); printf(“child process 2 is killed by parent!n”); lockf(stdout,0,0); exit(0); else printf(“p1n”); wait_mark=1; signal(16,stop) waiting(); lockf(stdout,1,0); printf(“
9、child process 1 is killed by parent!n”); lockf(stdout,0,0); exit(0); void waiting() while (wait_mark!=0); void stop()Wait_mark=0;【运行结果】child process 1 is killed by parent!child process 2 is killed by parent!Parent process is killed!【分析】使用系统调用signal()都放在一段程序的前面部分,而不是在其他接收信号处。这是因为signal()的执行只是为进程指定信号量
10、16或17的作用,以及分配相应的stop()过程连接的指针,从而,signal()函数必须在程序前面部分执行。编程实现例【任务】在上面程序中,增加语句signal(SIGINT,SIG_IGN)、signal(SIGQUIT,SIG_IGN),观察执行结果,并分析原因。【程序】#include #include #include int pid1,pid2;int endflag=0,pf1=0,pf2=0;void intdelete() kill(pid1,16); kill(pid2,17); endflag=1;void int1() printf(“child process 1 i
11、s killed by parent!n”);exit(0);void int2() printf(“child process 2 is killed by parent!n”);exit(0);main() int exitpid;signal(SIGINT,SIG_IGN);signal(SIGQUIT,SIG_IGN);while (pid1=fork()=-1);if (pid1=0) printf(“p1n”); signal(SIGUSER1,int1); signal(16,SIG_IGT) pause(); exit(0); elsewhile (pid2=fork()=-1); if (pid=0) printf(“p2n”); signal(SIGUSER2,int2); signal(17,SIG_IGT) pause(); exit(0); else printf(“parentn”); signal(SIGINT,intdelete); /*接收DEL信号,并转intdelete()*/ waitpid(-1,&exitpid,0); printf(“parent process is killed!n”); exit(0) 【运行结果】【分析】由于忽略了中断与退出信号,程序会一直保持阻塞状态而无法退出。
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1