我写一个系统关键程序用于一个Linux发行版本,我的发展。它需要重新启动本身关于接收某些信号,要尽量避免崩溃。问题是,在重新启动之后,我无法重新启用这一信号。那是信号不能接受的两倍。后execv()'ing本身,当新的处理呼叫的信号()设立的信号,SIG_DFL返回。每一个时间。甚至如果我把它连续两次--表示,它从来就不是设置在首位。是有些怪异的标志正在进行从原来的过程?

有帮助吗?

解决方案

你正在下降,恶的事实,你基本上是试图递归的把手一个信号。

当使用 signal() 注册一个信号处理程序,这一信号被阻断,直到信号处理返回的效果的核心/libc块,信号的时候信号处理程序,以及取消阻止它后信号处理程序的返回。因为你永远不会返回自信号处理程序(而不是你 execl 一个新的二进制), SIGUSR1 保持封锁和所以不是抓到2的时间。

这可以看出,通过检查 /proc/</pid>/status 之前和之后你发送第一 SIGUSR1.

之前:

$ cat /proc/<pid>/status | grep -E "Sig(Cgt|Blk)"
SigBlk: 0000000000000000
SigCgt: 0000000000000200

之后:

$ cat /proc/<pid>/status | grep -E "Sig(Cgt|Blk)"
SigBlk: 0000000000000200
SigCgt: 0000000000000200

注意, SigCgt 表示信号的10个注册的(数字是位域;第10位置,这相当于SIGUSR1,看看 man signal(7) 的数字)。 SigBlk 是空前的 SIGUSR 是送给你的过程,但是之后送的信号,它包含了 SIGUSR1.

你有两种方式来解决这个:

a)。手动解除 SIGUSR 之前的呼叫 execlsighandler:

sigset_t sigs;
sigprocmask(0, 0, &sigs);
sigdelset(&sigs, SIGUSR1);
sigprocmask(SIG_SETMASK, &sigs);

b)。使用 sigactionSA_NODEFER 标志,而不是的 signal 登记的信号处理程序。这将防止 SIGUSR1 从被阻止内部的信号处理程序:

struct sigaction act;
act.sa_handler = signalhandler;
act.sa_mask = 0;
act.sa_flags = SA_NODEFER;
sigaction(SIGUSR1, &act, 0);

其他提示

信号处理程序不会在exec之间继承,因为SIG_IGN会覆盖整个地址空间,而任何未重置的信号处理程序都将指向错误的位置。它没有被重置的唯一时间是它被设置为,例如,<=>,这不依赖于前 - <=>过程的地址空间。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top