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

标签 c pthreads signal-handling

我想暂停线程并恢复它。列出的方法很少here .但是我想到了使用 unistd.h 中的 pause() 库函数。

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

我注意到的一个是,当我发送 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;
}

最佳答案

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

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

更一般地说,信号掩码、信号和信号处理程序在信号接收时阻塞之间可能会发生许多不良交互。

此外,pause() 是相当非特定的,除非您将它与设置相当严格的信号掩码结合使用(在这种情况下,sigsuspend() 可能是更好的选择).但是,如果您设置了限制性信号掩码,那么您可能会干扰信号的其他用途。

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

关于c - 在信号处理程序中使用 `pause()` 有什么缺陷?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56685370/

相关文章:

c++ - C/C++ 中的快速字符串标记化

c - pthread_create 中的 restrict 是什么意思

c - 并行运行线程不可靠的行为

perl - 守护进程关闭和清理

c++ - 处理 POSIX 信号 : how to get stack trace without using backtrace_symbols?

c - 变量周围的堆栈已损坏

c - 访问二维指针数组

c - 为什么我们不经常使用 const?

c - 指向共享变量的指针互斥

multithreading - 在 linux 中信号处理程序的执行是不可抢占的吗?