关于signal 函数和 sigaction 函数的区别
注意 :
<1> sigaction
*一般用法:
19
20 phan.sa_handler = &sig_handler;
21 sigemptyset(&phan.sa_mask);
23 phan.sa_flags = 0; 或 //phan.sa_flags = SA_RESTART; 其效果和signal 一样
24 sigaction(SIGALRM, &phan, NULL);
*注意
一般不是重启动的函数,除非把sa_flag=SA_RESTART. 也就是说当信号到来,中断其阻塞的I/O操作,或其他阻塞的操作时,
他们会自动启动这些操作,而不会中断这些操作.而这些I/O操作会保持原来的阻塞状态就好好象根本没有信号到来一样.
<2>signal
函数是重启动的,当使用该函数安装信号处理函数时,其阻塞的操作将会被中断
实际使用例子:
/*
* test for alarm
*/
#include "apue.h"
void sig_handler(int signo);
void sig_handler2(int signo);
void pr_mask(const char *str);
int
main(void)
{
int i;
struct sigaction phan;
char str[100] = {'/0'};
//phan.sa_handler = &sig_handler2;
phan.sa_handler = &sig_handler;
sigemptyset(&phan.sa_mask);
//phan.sa_flags = SA_RESTART; //如果使用这一行,将会阻塞在read函数
phan.sa_flags = 0;
sigaction(SIGALRM, &phan, NULL);
//signal(SIGALRM, sig_handler2);
for(i=0;;i++){
alarm(3);
fprintf(stderr, "do something/n");
read(STDIN_FILENO, str, sizeof(str));
fprintf(stderr, "[%d] done/n", i);
//alarm(0);
//pause();
}
return(0);
}
void sig_handler(int signo)
{
struct sigaction phan;
switch(signo){
case SIGALRM:
//如果下面的函数将会阻塞在read函数.因为它会让阻塞的操作自动重启动
//signal(SIGALRM, sig_handler);
phan.sa_handler = &sig_handler;
sigemptyset(&phan.sa_mask);
phan.sa_flags = 0;
sigaction(SIGALRM, &phan, NULL);
pr_mask("sig_handler : "); //打印出信号掩码
fprintf(stderr, "time out/n");
break;
default:
fprintf(stderr, "[%d] ignores/n", signo);
}
}
void sig_handler2(int signo)
{
switch(signo){
case SIGALRM:
fprintf(stderr, "time out/n");
break;
default:
fprintf(stderr, "[%d] ignores/n", signo);
}
}
void
pr_mask(const char *str)
{
sigset_t sigset;
int errno_save;
errno_save = errno; /* we can be called by signal handlers */
if (sigprocmask(0, NULL, &sigset) < 0){
fprintf(stderr, "sigprocmask error");
exit(1);
}
printf("%s", str);
if (sigismember(&sigset, SIGINT)) printf("SIGINT ");
if (sigismember(&sigset, SIGQUIT)) printf("SIGQUIT ");
if (sigismember(&sigset, SIGUSR1)) printf("SIGUSR1 ");
if (sigismember(&sigset, SIGALRM)) printf("SIGALRM ");
/* remaining signals can go here */
printf("/n");
errno = errno_save;
}