sigaction SIGINT,程序在 & (background) 中运行,没有得到信号

sigaction SIGINT, programm run in shell with & (background) doesn't get the signal

本文关键字:运行 信号 background 程序 SIGINT sigaction      更新时间:2023-10-16

简单代码:

#include <signal.h>
#include <stdio.h>
#include <unistd.h>
#include <iostream>
using namespaces td;                                                             
bool unblock = false;                                                  
long int ile = 0;                                                 
void ouch(int sig) {
    cout << "signal " <<  sig << endl;                               
    unblock = true;                                                  
}                                                                
int main(){                                                          
    struct sigaction act;                                           
    act.sa_handler = ouch;                                           
    sigemptyset(&act.sa_mask);                                  
    act.sa_flags = 0;                                             
    sigaction(SIGINT, &act, 0);                                    
    do {                                                         
        cout << "." << endl;                                         
    } while(!unblock);                                                          
    cout << "EXIT" << endl;                                          
}

现在我编译代码,得到"a.out"。当我像这样运行 a.out 时:

[przemek@localhost test]$ ./a,out

它按预期运行,当我按 CTRL+C 时,程序会根据需要退出但是当我像这样运行程序时(在我的项目中需要):

[przemek@localhost test]$ ./a.out&

操作系统将控制权传递给外壳,我无法通过 CTRL+C 打破循环

我需要在 bash 脚本中运行此代码,我需要在后台运行它。在这种情况下,是否有可能以某种方式捕捉信号?

当您按ctrl-c时,您将信号 2 (SIGINT) 发送到当前进程(在终端前台运行的进程)。您可以使用kill将信号发送到在后台运行(以 & 开头)的进程:

$ kill -2 %%

当你说%%时,你的意思是最后一个后台进程。当然,您可以指定另一个。你需要知道它的PID(参见ps(1))或JobID(bash(1)/jobs)。

我还想指出,您只能在具有作业管理的 shell 中使用 % 表示法(例如在 bash 中)。当您不在这样的外壳中时,您只能使用 PID。

上次启动的进程的 PID 在 $! 中。这在某些脚本中可能很有用。