多线程C程序;如何杀死线程生成的进程?

多线程C程序;如何杀死线程生成的进程?,c,multithreading,fork,signals,C,Multithreading,Fork,Signals,情况: 我正在用C编写一个程序,它可以维护多个线程。线程结束后,将创建一个新线程 每个线程分叉-子线程通过exec()运行一个进程,父线程等待它完成 此外,还有一个等待信号的信号处理程序线程。如果检测到SIGINT,那么它会告诉主线程停止创建线程,以便最终所有线程都结束,程序可以退出 信号在所有线程中都被阻塞,当然信号处理程序线程除外 目标: 我想通过发送SIGTERM来终止程序。这将通过停止主线程创建新线程以及终止由线程创建的正在运行的进程来实现 问题: 如果所有线程中的信号都被阻塞,如何向正

情况:

我正在用C编写一个程序,它可以维护多个线程。线程结束后,将创建一个新线程

每个线程分叉-子线程通过exec()运行一个进程,父线程等待它完成

此外,还有一个等待信号的信号处理程序线程。如果检测到SIGINT,那么它会告诉主线程停止创建线程,以便最终所有线程都结束,程序可以退出

信号在所有线程中都被阻塞,当然信号处理程序线程除外

目标:

我想通过发送SIGTERM来终止程序。这将通过停止主线程创建新线程以及终止由线程创建的正在运行的进程来实现

问题:

如果所有线程中的信号都被阻塞,如何向正在运行的进程发送信号以终止它们


是否有办法使派生进程只接收从主程序发送的信号而不接收发送到主程序的信号?

在新进程组中创建所有子进程,然后将信号发送到该组

编辑: 下面是一些简单的代码,展示了进程如何通过一个信号改变它的组并控制子进程

#include <err.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

pid_t pgid; /* process group to kill */

void terminator( int s ) /* signal handler */
{
    printf( "[%d:%d] received signal %d, exiting\n",
        getpid(), getpgrp(), s );
    exit( 1 );
}

int main() /* program entry */
{
    printf( "[%d:%d] before first fork\n",
        getpid(), getpgrp() );

    switch ( fork()) /* try with and without first fork */
    {
        case -1: err( 1, "fork" );
        case 0: break;
        default: exit( 0 );
    }

    if ( signal( SIGTERM, terminator ) == SIG_ERR )
        err( 1, "signal" );

    if ( setpgrp() < 0 ) err( 1, "setpgrp" );
    if (( pgid = getpgrp()) < 0 ) err( 1, "getpgrp" );

    printf( "[%d:%d -> %d] before second fork\n",
        getpid(), getpgrp(), pgid );

    switch ( fork())
    {
        case -1: err( 1, "fork" );
        case 0: /* child */
        {
            printf( "child [%d:%d]\n", getpid(), getpgrp());
            sleep( 20 );
            break;
        }
        default: /* parent */
        {
            printf( "parent [%d:%d]\n", getpid(), getpgrp());
            sleep( 5 );
            killpg( pgid, SIGTERM );
            sleep( 20 );
        }
    }

    printf( "[%d:%d] exiting\n", getpid(), getpgrp());
    exit( 1 );
}

#包括
#包括
#包括
#包括
#包括
pid_t pgid;/*要杀死的进程组*/
无效终止符(int s)/*信号处理器*/
{
printf(“[%d:%d]接收到信号%d,正在退出\n”,
getpid(),getpgrp(),s);
出口(1);
}
int main()/*程序条目*/
{
printf(“[%d:%d]在第一个fork之前”\n”,
getpid(),getpgrp());
开关(fork())/*尝试使用和不使用第一个fork*/
{
案例1:错误(1,“叉”);
案例0:断裂;
默认值:退出(0);
}
if(信号(SIGTERM,终止符)=SIG_ERR)
错误(1,“信号”);
如果(setpgrp()<0)错误(1,“setpgrp”);
如果((pgid=getpgrp())<0)错误(1,“getpgrp”);
printf(“[%d:%d->%d]在第二个fork之前”\n”,
getpid(),getpgrp(),pgid);
开关(fork())
{
案例1:错误(1,“叉”);
案例0:/*儿童*/
{
printf(“子[%d:%d]\n”、getpid()、getpgrp());
睡眠(20);
打破
}
默认值:/*父级*/
{
printf(“父[%d:%d]\n”、getpid()、getpgrp());
睡眠(5);
killpg(pgid,SIGTERM);
睡眠(20);
}
}
printf(“[%d:%d]正在退出\n”、getpid()、getpgrp());
出口(1);
}
  • 在新流程组中创建所有子流程,然后向该组发送信号。(谢谢Nokolai)
  • 保留创建的所有流程的记录,并在需要时使用这些记录向其发出信号

  • 这正是我所做的,但它似乎工作不正常。我使用的组ID是主线程的PID-是这样吗?假设kill(),是否将信号发送到组ID的负数?也可以使用killpg()。是的,主进程调用它(pgrp是全局的):pgrp=getpid();setpgid(0,0);然后在每个线程中创建子进程:setpgid(0,pgrp);我试着杀死这样的过程:killpg(pgrp,SIGTERM);好的,我看到调用进程的groupID与它的PID相同,我用它来表示子进程的groupID,这就是信号永远不会到达的原因。有没有解决这个问题的建议?不要调用setpgid(0,pgrp);在子进程中-进程组id已被继承。