,单击此处编辑母版文本样式,第二级,第三级,第四级,第五级,单击此处编辑母版标题样式,Linux,进程间的通信,alarm,函数和,pause,函数,alarm,函数也称闹钟函数,是专门为,SIGALRM,信号而设,在指定的时间,seconds,秒后,将向进程本身发送,SIGALRM,信号。由于每个进程只能有一个闹钟,进程调用,alarm,后,任何以前的,alarm,调用都将无效。,0,Linux 进程间的通信alarm函数和pause函数0,Linux,进程间的通信,pause,函数是用于将调用的进程挂起直到捕捉到信号为止,常用来判断信号是否已到达。这两个函数原型如下:,1,Linux 进程间的通信pause函数是用于将调用的进程挂起,Linux,进程间的通信,unsigned int alarm(unsigned int seconds);,int pause(void);,参数,seconds,为指定的闹钟秒数。调用成功返回,0,,错误返回,-1,。如果,seconds,为,0,,那么进程内将不再包含任何闹钟。,2,Linux 进程间的通信unsigned int alarm,Linux,进程间的通信,在,I/O,操作中,当读取一个低速设备且该设备可能阻塞时,则希望超过一定的时间后就停止执行该操作。下面的例子利用,alarm(),函数实现了这个功能。,3,Linux 进程间的通信在I/O操作中,当读取一个低速设备且,Linux,进程间的通信,例子,4,Linux 进程间的通信例子4,Linux,进程间的通信,abort,函数,此函数向进程发送,SIGABORT,信号,默认情况下进程会异常退出。该函数的函数原型为:,void abort,(,void,);,该函数没有参数也没有返回值,使用很简单。,5,Linux 进程间的通信abort函数5,Linux,进程间的通信,信号的处理,如果进程要处理某一信号,那么要在进程中注册该信号。注册信号主要用来确定信号值与处理之间的映射关系,即进程将要处理那个信号,该信号被传递给进程时,将执行何种操作。,6,Linux 进程间的通信信号的处理6,Linux,进程间的通信,主要有两个函数实现信号的注册:,1.void(*signal(int sig,void(*func)(int)(int);,这个复杂的声明是一个需要两个参数的函数,,sig,与,func,。要捕获或是忽略的信号是由,sig,参数来指定的。,7,Linux 进程间的通信主要有两个函数实现信号的注册:7,Linux,进程间的通信,当接收到指定的信号时要调用的函数是由,func,来指定的。这个函数必须是带有一个,int,作为参数,(,接收到的信号,),,并且其类型为,void,。,8,Linux 进程间的通信当接收到指定的信号时要调用的函数是由,Linux,进程间的通信,例子会使得我们的解释更为清晰。我们知道,按下,Ctrl+C,键会产生,SIGINT,信号,进程对该信号的默认响应是结束本进程,而下面的实验程序截取并重写了对,SIGINT,信号的处理,因此按下,Ctrl+C,时会输出一条信息,而不是用结束来响应,SIGINT,信号。,9,Linux 进程间的通信例子会使得我们的解释更为清晰。我们知,Linux,进程间的通信,实验,:,信号处理,10,Linux 进程间的通信实验:信号处理 10,Linux,进程间的通信,运行结果,11,Linux 进程间的通信运行结果11,Linux,进程间的通信,函数,sig_int,会响应作为参数,sig,传递的信号。这个函数会在信号发生时调用,它将输出一条字符串信息。,12,Linux 进程间的通信函数sig_int会响应作为参数si,Linux,进程间的通信,需要注意的是,由,signal,函数注册的信号处理函数执行完毕后,对信号的响应将还原为系统默认的处理方式,因此需要重新注册信号。如果不重新注册信号,那么下次按下,Ctrl+C,键时,系统将按,SIGINT,默认的处理方式结束本进程。,13,Linux 进程间的通信需要注意的是,由signal函数注册,Linux,进程间的通信,2.int sigaction(int signum,const struct sigaction*act,struct sigaction*oldact);,signum,:要操作的信号,除,SIGKILL,及,SIGSTOP,以外的任何一个特定有效的信号。,14,Linux 进程间的通信2.int sigaction(i,Linux,进程间的通信,act,:指向结构,sigaction,的一个实例的指针,在结构,sigaction,中,指定了对特定信号的处理,可以为空,进程会以默认方式对信号处理。,oldact,:原来对信号的处理方式,可指定为,NULL,。,15,Linux 进程间的通信act:指向结构sigaction的,Linux,进程间的通信,返回值:,0,表示成功,,-1,表示有错误发生。,struct sigaction,类型用来描述对信号的处理,定义如下:,16,Linux 进程间的通信返回值:0 表示成功,-1 表示有错,Linux,进程间的通信,struct sigaction,void (*sa_handler)(int);,void (*sa_sigaction)(int,siginfo_t*,void*);,sigset_t sa_mask;,int sa_flags;,void (*sa_restorer)(void);,17,Linux 进程间的通信struct sigaction,Linux,进程间的通信,各字段含义如下:,sa_handler:,是一个函数型指针,这个指针指向一个函数,该函数就是要进行信号处理的函数,其可以带一个参数。,sa_sigaction,、,sa_restore,和,sa_handler,的含义相同,只是参数不同。,18,Linux 进程间的通信各字段含义如下:18,Linux,进程间的通信,sa_flag,:指定了对信号进行处理的选项,进一步学习之前,可暂时设定为,0.,sa_mask:,用来设置信号屏蔽字,该屏蔽字由一个信号集定义。进一步学习之前,可暂时设定为空集。,19,Linux 进程间的通信sa_flag:指定了对信号进行处理,Linux,进程间的通信,sigaction,函数的使用和,signal,函数的使用基本相同,事实上在现在的很多,Linux,平台上都是用,sigaction,函数实现,signal,函数的。因此,当熟练掌握该函数后,应尽量使用该函数而不是,signal,函数。,20,Linux 进程间的通信sigaction函数的使用和sig,Linux,进程间的通信,下面将前面的例子用,sigaction,函数重写一遍。,21,Linux 进程间的通信下面将前面的例子用sigaction,Linux,进程间的通信,与,signal,函数略有不同的,由,sigaction,函数设置的信号处理函数所捕捉到的信号在默认情况下是不会被重置的。因此不需要重新注册信号。这是两个函数在使用上的区别。,22,Linux 进程间的通信与signal函数略有不同的,由si,Linux,进程间的通信,运行结果,23,Linux 进程间的通信运行结果23,