如何多次发送 SIGINT 信号

Posted

技术标签:

【中文标题】如何多次发送 SIGINT 信号【英文标题】:how to send SIGINT signal multiple times 【发布时间】:2015-07-15 17:50:35 【问题描述】:

我正在尝试从其他线程向主线程发送 SIGINT 信号。主线程已经为信号分配了一个处理程序。当我发送第一个信号时,它被处理程序捕获。但我想连续发送信号。但在处理完第一个信号后,程序终止。我放了一个while循环。所以我期望它应该继续发送这些信号。以下是我的代码

#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>

static void catch_function(int signo) 
    puts("Interactive attention signal caught.");


DWORD WINAPI MyThreadFunction( LPVOID lpParam ) 

    while(1)
    
        Sleep(50);
        puts("Raising the interactive attention signal.");
        if (raise(SIGINT) != 0) 
        
            fputs("Error raising the signal.\n", stderr);
            return EXIT_FAILURE;
        
    
return 0;



int main(void) 

     if (signal(SIGINT, catch_function) == SIG_ERR) 
    fputs("An error occurred while setting a signal handler.\n", stderr);
    return EXIT_FAILURE;
    

    HANDLE thread;
    DWORD  threadId;
    thread = CreateThread(NULL, 0, &MyThreadFunction, NULL, 0, &threadId);
    if(!thread)
    
        printf("CreateThread() failed");
    

    while(1)
    
        Sleep(50);
    
    puts("Exiting.");
    return 0;

下面代码的输出是

Raising the interactive attention signal.
Interactive attention signal caught.
Raising the interactive attention signal.

我也尝试过使用一个简单的例子。在这里,我发送了 3 次信号,但只有第一次信号被捕获。之后程序终止。以下是代码

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

void signal_handler(int signal)

    printf("Received signal %d\n", signal);


int main(void)

    // Install a signal handler.
    signal(SIGINT, signal_handler);

    printf("Sending signal %d\n", SIGINT);
    raise(SIGINT);
    raise(SIGINT);
    raise(SIGINT);
    printf("Exit main()\n");

输出是

sending signal 2
Received signal 2

所以我想知道如何继续从一个线程向其他线程发送一些信号?我希望我的一个线程将发送 SIGINT 信号,而 main 将捕获它们并相应地执行一些操作。

【问题讨论】:

你为什么使用信号来中断作为“注意”信号?它通常是尝试使用 CTRL-C 取消程序时发送的信号。如果您发现它,并且遇到问题导致用户想要中断您的程序,那么使用通常的标准方式将不再可能。您可能想使用例如SIGUSR1SIGUSR2. @JoachimPileborg 我也想为 Windows 做这件事。我想我不能为此使用 SIGUSER1 和 SIGUSR2 。如果我不正确,请告诉我。 @JoachimPileborg 你能看看***.com/questions/31461171/… 【参考方案1】:

通常在第一个信号之后,信号处理程序被重置为SIG_DFL(Unix V 信号)和SIG_INT 退出程序的默认行为。这是你观察到的。所以它需要再次重新安装处理程序。在处理程序中再次安装它:

void signal_handler(int signal)

    signal(SIGINT, signal_handler);
    printf("Received signal %d\n", signal);

更好的方法是使用sigaction,因为它没有这种行为。

【讨论】:

使用sigaction可以控制带有标志的行为。 是的,不必重新安装是一个明显的优势。 @BlueMoon 你能看看***.com/questions/31461171/… 但仍然sigaction(或任何方法)不能保证接收所有生成的信号

以上是关于如何多次发送 SIGINT 信号的主要内容,如果未能解决你的问题,请参考以下文章

Python 在 Windows 上发送 SIGINT 信号子进程

linux信号 SIGINT SIGTERM SIGKILL

如何仅在 C 中将 SIGINT 发送到后台进程

Linux的shell脚本trap信号处理

linux信号解释

Linux - 操作系统信号