日期:2014-05-16  浏览次数:20708 次

用sigaction设置了捕捉函数,为什么进程仍然会被终止
捕捉函数什么都没干,仅仅一个return。
sigaction结构的sa_mask成员也设置成该信号了,但进程还是会被该信号给终止掉,不解。
该信号是我用timer_create生成的timer产生的。

另外顺便问一下,貌似被信号终结时不一定都会产生core文件,只有非法内存访问才会产生么?

------解决方案--------------------
大多数系统上,以下信号会产生core文件, 其中又以SIGSEGV最常见。
SIGABRT
SIGBUS
SIGFPE
SIGILL
SIGQUIT
SIGSEGV
SIGSYS
SIGTRAP
------解决方案--------------------
struct sigaction {
void (*sa_handler)(int);
void (*sa_sigaction)(int, siginfo_t *, void *);
sigset_t sa_mask;
int sa_flags;
void (*sa_restorer)(void);
};

操作这个结构体有一点要注意, sa_handler和sigaction是在一个union里的,只有一个能赋值,原文如下:
On some architectures a union is involved: do not assign to both sa_handler and sa_sigaction.

使用这个结构体的时候先bzero清空整个结构体,然后赋值sa_handler即可,不需要赋值sa_mask,那是信号处理中的信号掩码, 通常是不需要额外屏蔽什么信号的, 默认就会屏蔽当前被处理的信号,原文如下:
sa_mask specifies a mask of signals which should be blocked (i.e., added to the signal mask of the thread in which the signal handler is invoked) during
execution of the signal handler. In addition, the signal which triggered the handler will be blocked, unless the SA_NODEFER flag is used.

另外,

int sigaction(int signum, const struct sigaction *act,
struct sigaction *oldact);

选择是哪个信号被什么函数处理是sigaction函数调用时选择的signum。
------解决方案--------------------
TCP的话肯定是不对的,字节流是按序发出的,你发一半数据又插另一半数据是定然不行的,也不是不能编码,只不过必须做好信号屏蔽,保证将未送出的数据缓冲起来并注册写事件,在信号处理函数中将要发送的数据继续追加到缓冲区,而不是穿插着write。 如果不这么编码,那就基本没办法实现你的设想了,给你个框架。

这是main loop:

sigprocmask //屏蔽所有信号
if (buffer空)
{
ret = write(fd, msg, len);
if (ret == -1) memcpy(buffer, msg, len);
else if (ret < len) memcpy(buffer, msg+ret, len - ret);

if (ret == -1 || ret < len) 添加fd的写事件;
}
else
{
memcpy(buffer + buffer_cur_len, msg, len);
}
sigprocmask //解除屏蔽

这是信号处理函数里的判定:

if (buffer is not empty)
{
memcpy(buffer + buffer_cur_len , local msg, len);
}
else
{
ret = write(fd, local msg, len);
if (ret == -1) memcpy(buffer, local_msg, len);
else if (ret < len) memcpy(buffer, local_msg+ret, len-ret);

if (ret == -1 || ret < len) 注册fd的写事件;
}
------解决方案--------------------
探讨

顺便再问一个问题,如果用write写一个socket写了一部分数据,这时候被一个信号中断,而信号处理函数中也用write写同一个socket,该处理函数返回后,前一个write重启继续写,这时候数据会不会交错?