【问题标题】:Catching SIGTERM in C with more processes用更多进程在 C 中捕获 SIGTERM
【发布时间】:2019-11-05 12:52:48
【问题描述】:

我需要我的程序通过捕获 SIGTERM 信号正确终止其所有进程,但即使是 CTRL+C(我认为是 SIGINT)。如何修改它以使其正常工作? 我试图只发布必要的代码,以免在程序运行时造成混乱,我只需要添加这个信号管理。

include <signal.h>
int nproc = 10;
int listaPID[10];
int forkValue;

int main (void){  
    signal(SIGTERM,signalHandler);
    //...
    createSM();
    for(int i=0; i<nproc; i++){ 
        forkValue = fork();       
        if(forkValue == 0)
            break;
        listaPid[i] = forkValue;    
    }

    if (forkValue==0){
        //child's tasks
        removeSM();
        exit(0);
    }
    //parent's tasks
    deleteSM(); 
    exit(0);
}

void signalHandler(int sig){ 
    //if parent, kill all of its childs + remove and delete shared memory + exit
    if (forkValue>0){
        for(int i=0;i<nproc;i++)
            kill((listaPid[i]),SIGTERM);
        deleteSM();
        exit(0);
    }
    //if son, remove shared memory + exit
    else {
        removeSM();
        exit(0);
    }
}

【问题讨论】:

  • Ctrl-C 触发 SIGINT 而不是 SIGTERM
  • "是否正确" 由于您显示的代码不完整,无法判断是否正确。
  • 其实,问题是什么?
  • 不,这是不正确的。 exit(3) 函数不是信号安全的。根据 os & libc 类型和版本、用于编译代码的选项和月相,signal() 函数的工作方式不同,因此完全无法预测会发生什么。
  • 我可以对其进行修改以使其正常工作”这可能意味着当前它的行为与您的预期不同。所以告诉它是如何表现的。

标签: c signals fork sigterm


【解决方案1】:

^C 生成SIGINTR,因此您还必须为该信号安装处理程序。除了SIGTERM 之外,您可能还需要为SIGQUIT^] 中断键)和SIGHUP(会话结束)安装allso 信号处理程序。

在我看来,如果要杀死一个组中的所有进程,最好在父进程上创建一个进程组(setpgrp(0,0);,见setpgrp(2)),然后杀死该进程组(到 kill(2) 一个进程组,您使用组更改符号的 id,kill(SIGTERM, -getpgrp());,(请参阅 kill(2)setpgrp(2) 的手册页)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-08-27
    • 1970-01-01
    • 2018-10-29
    • 2017-08-22
    • 1970-01-01
    • 1970-01-01
    • 2021-06-23
    相关资源
    最近更新 更多