C 在信号处理程序中使用'pause()'有哪些陷阱?

C 在信号处理程序中使用'pause()'有哪些陷阱?,c,pthreads,signal-handling,C,Pthreads,Signal Handling,我想挂起线程并恢复它。列出的方法很少。但是我想使用unistd.h中的pause()库函数 在信号处理程序中使用暂停有哪些缺陷 我注意到的一点是,当我发送0以暂停线程并再次发送0时,我的信号会排队。我需要发送1两次才能恢复线程 我想像这样的情况可能还有很多。如果我想在信号处理程序中使用pause()或sleep(),如何处理这种情况 #include <stdio.h> #include <unistd.h> #include <pthread.h> #inc

我想挂起线程并恢复它。列出的方法很少。但是我想使用
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;
}
#包括
#包括
#包括
#包括
#包括
静态布尔线程_ready=false;
静态无效cb_信号(内部信号)
{
如果(信号==SIGUSR1)
暂停();
否则如果(信号==SIGUSR2)
;
}
静态void*线程作业(void*忽略)
{
int i=0;
结构动作法;
sigemptyset(和act.sa_面具);
act.sa_标志=0;
act.sa_handler=cb_sig;
if(sigaction(SIGUSR1,&act,NULL)=-1)
printf(“无法处理siguser1\n”);
if(sigaction(SIGUSR2,&act,NULL)=-1)
printf(“无法处理siguser2\n”);
线程_ready=true;
而(1){
printf(“线程计数器:%d\n”,i++);
睡眠(1);
}
返回NULL;
}
int main()
{
布尔跑;
int用户输入;
pthread\u t线程;
if(pthread_create(&thread,NULL,thread_job,NULL))
返回-1;
而(!线程_就绪);
for(running=true;running;){
printf(“0:暂停线程,1:恢复线程,-1:退出\n”);
scanf(“%d”和用户输入);
开关(用户输入){
案例1:
运行=错误;
打破
案例0:
pthread_kill(线程,SIGUSR1);
打破
案例1:
pthread_kill(线程,SIGUSR2);
打破
}
}
pthread_kill(线程,SIGKILL);
返回0;
}

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

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

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

此外,
pause()
是非特定的,除非您将其与设置限制性较强的信号掩码结合使用(在这种情况下,
sigsupspend()
可能是更好的选择)。但如果设置了限制性信号掩码,则可能会干扰信号的其他用途


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

为什么要在信号处理程序中使用
pause()
sleep()
?为什么您的
main()
函数不直接挂起或暂停线程,而不使用信号?一般来说,终止一个线程是有问题的-通常最好是将信息获取到线程,使其结束干净,而不是试图直接杀死它。对不起,我忘了提到我的用例,考虑线程池,所以作业将被传递给线程。现在,线程正在执行作业,我希望线程池具有暂停/恢复功能。因此线程即使在工作中间也应该暂停。将有一个监视线程,负责挂起和恢复池中的其他线程。如果程序中的一个线程挂起另一个线程,它将被挂起,即使在“作业中间”。恢复时,将从暂停的位置继续。不需要信号。是的,它应该恢复它的工作,也就是说,在它被挂起的地方恢复。如果我可以将信号处理程序与中断联系起来,信号处理程序应该很短,并且立即返回,对吗?因此,我需要延迟处理。@Shubham中断服务例程应该尽可能短和快。通常,它们用于简单地设置标志和返回;程序的另一部分将作用于该设置标志。