我在使用SIGUSR1
和SIGUSR2
信号时遇到了问题。实际上,我有一个客户端程序发送二进制字符串*str
(例如:1100111
为g字母)到服务器程序,通过使用SIGUSR1
信号为'1'和SIGUSR2
信号为'2'。服务器像这样接收它们:
signal(SIGUSR1, my_handler);
signal(SIGUSR2, my_handler);
pause();
my_handler对应:
void my_handler(int signum) {
if (signum == SIGUSR1)
printf("1");
else
printf("0"); }
但问题是,例如'g'字符的输出是01
,因此似乎接收不正确。我应该怎么做才能从我的服务器打印1100111
?提前谢谢你:)
信号未排队
通常,标准信号不是,但实时信号是,所以这些是另一种选择。但是使用两个(或更多)信号有两个其他问题:
- 一个信号可以中断另一个信号的处理;这可以通过在信号处理期间阻塞两个(或多个)来解决。
- 即使实时信号排队(这实现了接收的信号和发送的信号一样多),这并不能实现不同的信号按照发送的顺序传递给处理程序;
因此,为了解决第二个问题,我们必须只使用一个信号。(这也使第一个问题消失,因为一个信号在处理过程中被自动阻塞。)当然,这意味着我们需要另一种方式来传递您想要发送的信息。幸运的是,有sigqueue()
发送一个值随着信号。为了在信号处理程序中访问这个值,我们必须使用sigaction()
而不是signal()
来安装它。这样,服务器程序的相关部分变成
void my_handler(int signum, siginfo_t *info, void *uc)
{
write(1, &(char){'0'+info->si_value.sival_int}, 1);
}
…
struct sigaction act = { .sa_sigaction = my_handler,
.sa_flags = SA_SIGINFO };
sigemptyset(&act.sa_mask);
sigaction(SIGRTMIN, &act, NULL);
for (; ; ) pause();
和客户端程序发送带有序列
的示例模式sigqueue(pid, SIGRTMIN, (union sigval){1});
sigqueue(pid, SIGRTMIN, (union sigval){1});
sigqueue(pid, SIGRTMIN, (union sigval){0});
sigqueue(pid, SIGRTMIN, (union sigval){0});
sigqueue(pid, SIGRTMIN, (union sigval){1});
sigqueue(pid, SIGRTMIN, (union sigval){1});
sigqueue(pid, SIGRTMIN, (union sigval){1});