如何中断pselect?

问题描述 投票:0回答:1

这是我的代码,我无法使用信号中断主循环。当我启动时,会调用 SIGUSR1 信号处理程序,但我不会取消阻止 pselect。

#include <errno.h>
#include <signal.h>
#include <stdio.h>

int end = 1;

void handler(int sig) {
    end = 1;
}

int main() {
    sigset_t blockset;
    struct sigaction sa;
    int res;

    /* Block the signal */
    sigemptyset(&blockset);
    sigaddset(&blockset, SIGUSR1);
    sigprocmask(SIG_BLOCK, &blockset, NULL);

    /* Install handler */
    sa.sa_sigaction = handler;
    sigemptyset(&sa.sa_mask);
    sa.sa_flags = SA_RESTART;
    sigaction(SIGUSR1, &sa, NULL);

    /* Unblock signal; wait for signal */
    while(end) {
        sigemptyset(&emptyset);    /* Signal mask to use during pselect() */
        res = pselect(0, NULL, NULL, NULL, NULL, &emptyset);
        if (errno == EINTR)
            printf("Interrupted by SIGUSR1.");
    }
}
c signals posix-select
1个回答
3
投票

一开始我以为是因为你使用了

SA_RESTART
。这与你想要的相反。然而,事实证明
pselect
忽略了
SA_RESTART
,所以不是这样的。


事实证明,

pselect
is回归,
errno
is
EINTR
。您只是没有看到该消息,因为您没有刷新
stdout
的缓冲区!

您可以在将输出发送到

fflush
后使用
stdout
来完成此操作。

fflush(stdout);

但是

stdout
在输出到终端时是行缓冲的,因此只需添加缺少的换行符即可解决问题。

printf("Interrupted by SIGUSR1.\n");

如果不是第二个错误,您甚至不会注意到上述问题。

stdout
通常在程序退出时刷新,但你的程序不会退出,因为你有

int end = 1;

void handler(int sig) {
    end = 1;
}

while (end) { ... }

当你想做的时候

int end = 0;

void handler(int sig) {
    end = 1;
}

while (!end) { ... }
© www.soinside.com 2019 - 2024. All rights reserved.