【预备知识】
进程软中断通信涉及的系统调用描述如下。
1.kill()
进程用kill()向一个进程或一组进程发送一个信号。系统调用格式为int kill(pid,sig)。其中,pid是一个或一组进程的标识符,sig是要发送的软中断信号。信号的发送分如下三种情况。
pid>0时,核心将信号发送给进程pid。
pid=0时,核心将信号发送给与发送进程同组的所用进程。
pid=-1时,核心将信号发送给所有用户标识符真正等于发送进程的有效用户标识号的进程。
2.signal(sig,function)
接收信号的程序用signal()来实现对处理方式的预置,允许调用进程控制软中断信号。系统调用格式为signal(sig function),此时需包含头文件signal.h。其中,sig用于指定信号的类型,sig为0则表示没有收到任何信号,其余类型如表所示。
调用函数使用如下头文件:
#include<signal.h>
参数定义如下:
signal (sig,function)
int sig;
void(*func) ();
function是该进程中的一个函数地址,在核心返回用户态时,它以软中断信号的序号作为参数调用该函数,对除了信号SIGKILL、SIGTRAP和SIGPWR以外的信号,核心自动重新设置软中断信号处理程序的值为SIG_DFL,进程不能捕获SIGKILL信号。
function的解释如下:
(1)function=1时,进程对sig类信号不做任何处理便立即返回,亦即屏蔽该类型号。
(2)function=0时,默认值,进程收到sig信号后终止自己。
(3)function为非0、非1类整数时,执行用户设置的软中断处理程序。
(4)signal(SIGINT,SIG_IGN);来让进程忽略SIGINT信号.
信号的类型
值
名字
说明
01
SIGHUP
挂起(hangup)
02
SIGINT
中断,当用户从键盘按“^c”键或“^break”键时
03
SIGQUIT
退出,当用户从键盘按“quit“键时
04
SIGILL
非法指令
05
SIGTRAP
跟踪陷阱(trace trap)
06
SIGIOT
IOT指令
07
SIGEMT
EMT指令
08
SIGFPE
浮点运算溢出
09
SIGKILL
终止进程
10
SIGBUS
总线错误
11
SIGSEGV
段违例,进程试图去访问其虚地址空间以外的位置
12
SIGSYS
系统调用中参数错,如系统调用号非法
13
SIGPIPE
向某个非读管道中写入数据
14
SIGALRM
闹钟。当进程希望在某时间后接收信号时发此信号
15
SIGTERM
软件终止(software termination)
16
SIGUSR1
用户自定义信号1
17
SIGUSR2
用户自定义信号2
18
SIGCLD
某个子进程死
19
SIGPWR
电源故障
编程实现例<一>
【任务】
编程实现,父进程生成子进程,父进程发送信号并等待,子进程接收信号并完成某种功能,然后自我终止并唤醒父进程。
【程序】
#include <stdio.h> #include <signal.h> #include <unistd.h> 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”); } else { sleep(10); printf(“Child: A signal from my Parent is received ! \n”); exit(); } } func() { printf(“It is signal 17 processing function ! \n”) }
修改后的代码:
【运行结果】
【分析】
这是一个父子进程通信的例子。父进程生成子进程,发送信号给子进程,并等待子进程完成某种功能。子进程接收信号,并执行处理函数后自我终止,唤醒父进程。当父进程发送信号给子进程后,子进程会等待10秒钟后接收到信号,并执行信号处理函数,然后自我终止,唤醒父进程。父进程等待子进程结束后输出完成的消息。
编程实现例<二>
【任务】
编制一程,使用系统调用fork()创建两个子进程,再用系统调用signal()让父进程捕捉键盘上来的中断信号(即DEL键),当捕捉到中断信号后,父进程用系统调用kill()向两个子进程发出信号,子进程捕捉到信号后,分别输出下列信息后终止。
child process 1 is killed by parent!
child process 2 is killed by parent!
父进程等待两个子进程终止后,输出以下信息后终止。
Parent process is killed!
【程序】
#include <stdio.h> #include <signal.h> #include <unistd.h> int waiting(),stop(); int wait_mark; main() { int p1,p2; while ((p1=fork())==-1); if (p1>0) { while ((p2=fork())==-1); if (p2>0) { printf(“parent\n”); wait_mark=1; signal(SIGINT,stop); /*接收DEL信号,并转stop()*/ waiting(); kill(p1,16); /*向P1发中断信号16*/ kill(p2,17); /*向P2发中断信号17*/ wait(0); wait(0); printf(“parent process is killed!\n”); exit(0) } else { printf(“p2\n”); wait_mark=1; signal(17,stop); signal(SIGINT,SIG_IGN); waiting(); lockf(stdout,1,0); printf(“child process 2 is killed by parent!\n”); lockf(stdout,0,0); exit(0); } } else { printf(“p1\n”); wait_mark=1; signal(16,stop) signal(SIGINT,SIG_IGN); waiting(); lockf(stdout,1,0); printf(“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; }
修改后的代码:
【运行结果】
【分析】
这是一个父进程生成两个子进程的例子。父进程会等待子进程执行完毕后输出 "parent process is killed!" 的消息,并向子进程发送中断信号。子进程接收到中断信号后输出相应的消息。当父进程发送中断信号给子进程后,子进程会输出相应的消息。父进程会等待子进程执行完毕后输出 "parent process is killed!" 的消息
编程实现例<三>
【任务】
在上面程序中,增加语句signal(SIGINT,SIG_IGN)、signal(SIGQUIT,SIG_IGN),观察执行结果,并分析原因。
【程序】
#include <stdio.h> #include <signal.h> #include <unistd.h> 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 is 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(“p1\n”); signal(SIGUSER1,int1); signal(16,SIG_IGT) pause(); exit(0); } else { while ((pid2=fork())==-1); if (pid==0) { printf(“p2\n”); signal(SIGUSER2,int2); signal(17,SIG_IGT) pause(); exit(0); } else { printf(“parent\n”); signal(SIGINT,intdelete); /*接收DEL信号,并转intdelete()*/ waitpid(-1,&exitpid,0); printf(“parent process is killed!\n”); exit(0) } } }
修改后的代码:
【运行结果】
【分析】
程序中增加了两个语句 signal(SIGINT, SIG_IGN) 和 signal(SIGQUIT, SIG_IGN),将 SIGINT 和 SIGQUIT 信号的处理方式设置为忽略。原因是,
SIGINT 是由终端发送的中断信号,通常由用户按下 Ctrl+C 触发。SIGQUIT 是由终端发送的退出信号,通常由用户按下 Ctrl+\ 触发。
通过将这两个信号的处理方式设置为忽略 (SIG_IGN),程序会忽略这两个信号,不执行默认的信号处理行为。因此,当用户按下对应的终端键时,程序中的子进程不会被杀死,也不会输出相应的消息。
进程软中断通信实验
最新推荐文章于 2024-05-22 12:59:31 发布