如何中断pselect?

时间:2014-08-08 19:49:07

标签: c select signals

这里有我的代码,我无法使用信号中断主循环。当我启动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.");
    }
}

1 个答案:

答案 0 :(得分:3)

起初,我认为这是因为您使用的是SA_RESTART。这与你想要的相反。但是,事实证明pselect忽略了SA_RESTART,所以不是这样。


事实证明,pselect 正在返回,而errno 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) { ... }