1.signal 是比较传统的linux函数,存在缺陷,表现在信号不可靠(丢失...), 绝对不要使用(linux保留该函数只是为了兼容)
eg: 通常使用signal(SIGPIPE, SIG_IGN)用以忽略 sigpipe,但是在多线程中只在主线程设置却是不够的,一种解决方法是在每个线程都设置,
根本原因在于如果一个sigpipe正在处理的话,新来的sigpipe信号会采用默认处理方式处理(而默认的处理方式就是让进程退出);
真正避免sigpipe的正确方法是:
方法一:
sigset_t signal_mask;
sigemptyset (&signal_mask);
sigaddset (&signal_mask, SIGPIPE);
int rc = pthread_sigmask (SIG_BLOCK, &signal_mask, NULL);
if (rc != 0)
{
printf("block sigpipe error\n");
}
方法二:
使用sigaction函数
void sigcatcher(int sig, int /*sinfo*/, struct sigcontext* /*sctxt*/)
{
}
struct sigaction act;
sigemptyset(&act.sa_mask); //清空,初始化
act.sa_flags = 0;
act.sa_handler = (void(*)(int))&sigcatcher; //也可用SIG_IGN
(void)::sigaction(SIGPIPE, &act, NULL);
2.信号处理函数需要注意不能包含不可重入的函数,如果与程序中其它函数冲突会造成不可预料的后果(相当于不可重入函数在多线程中)
3.sigprocmask可以用来屏蔽信号
eg: ppoll中相当于对poll使用如下用法:
int timeout;
sigprocmask(SIG_SETMASK, &sigmask, &origmask); //设置信号屏蔽
ready = poll(&fds, nfds, timeout);
sigprocmask(SIG_SETMASK, &origmask, NULL); //恢复