在信号处理程序中使用`pause()`有什么陷阱?

shu*_*ham 0 c pthreads signal-handling

我想暂停线程并恢复它。有上市一些方法在这里。但是我想到了pause()从使用库函数unistd.h

在信号处理程序中使用暂停有哪些陷阱?

我注意到的一个是,当我发送0到暂停线程并0再次发送时,我的信号已排队。我需要发送1两次以恢复线程。

我猜可能还会有更多类似的情况。如果要使用信号处理程序pause()sleep()在信号处理程序中如何处理此类情况。

#include <stdio.h>
#include <unistd.h>
#include <pthread.h>
#include <signal.h>
#include <stdbool.h>

static bool thread_ready = false;

static void cb_sig(int signal)
{
        if (signal == SIGUSR1)
                pause();
        else if (signal == SIGUSR2)
                ;
}

static void *thread_job(void *ignore)
{
        int i = 0;
        struct sigaction act;

        sigemptyset(&act.sa_mask);
        act.sa_flags = 0;
        act.sa_handler = cb_sig;

        if (sigaction(SIGUSR1, &act, NULL) == -1)
                printf("unable to handle siguser1\n");
        if (sigaction(SIGUSR2, &act, NULL) == -1)
                printf("unable to handle siguser2\n");

        thread_ready = true;
        while (1) {
                printf("thread counter: %d\n", i++);
                sleep(1);
        }

        return NULL;
}

int main()
{
        bool running;
        int user_input;
        pthread_t thread;

        if (pthread_create(&thread, NULL, thread_job, NULL))
                return -1;

        while (!thread_ready);

        for (running = true; running; ) {
                printf("0: pause thread, 1: resume thread, -1: exit\n");
                scanf("%d", &user_input);

                switch(user_input) {
                case -1:
                        running = false;
                        break;
                case 0:
                        pthread_kill(thread, SIGUSR1);
                        break;
                case 1:
                        pthread_kill(thread, SIGUSR2);
                        break;
                }
        }

        pthread_kill(thread, SIGKILL);
        return 0;
}
Run Code Online (Sandbox Code Playgroud)

Joh*_*ger 6

即使从技术上讲,信号处理程序也不应sleep(),也可能不应pause(),这两个函数都是异步信号安全的。信号处理程序应运行迅速并最小化,或者(最好是)完全避免阻塞。

至于特定的陷阱,您已经注意到一个:默认情况下,信号在其处理程序运行时会自动被阻止。可以通过避免这种情况的方式来安装处理程序,但这在这里无济于事:如果您一直发送由特定处理程序处理的信号,则在该处理程序中始终会阻塞至少一个线程。如果您一直将它们发送到同一线程,则该线程将永远不会解除阻塞。

更一般地,在信号屏蔽,信号传递和信号处理程序阻塞信号接收之间可能发生许多不良的交互。

而且,pause()除非您将其与设置相当严格的信号掩码结合使用(否则sigsuspend()可能是更好的选择),否则它是非特定的。但是,如果您设置了限制性信号掩码,则可能会干扰信号的其他用途。

除了避免在信号处理程序中使用pause()sleep(),不要“处理”此类问题。