首页 > 解决方案 > 向子进程发送信号时出现问题

问题描述

我有一台服务器,它在启动时使用该SetConsoleCtrlHandler()功能设置控制台处理程序并创建许多子进程。
我的目标是这样的:

这是我的代码:

//handler for server.c
BOOL WINAPI CtrlHandler( DWORD fdwCtrlType ) 
{ 

    //CTRL_C_EVENT
    if(fdwCtrlType == CTRL_BREAK_EVENT)
    {
        newConf=1;
        return TRUE;
    }
    else if(fdwCtrlType == CTRL_C_EVENT)
    {
        //send CTRL+C to all process with the same groupId of calling process
        GenerateConsoleCtrlEvent(0,0);//
        return FALSE;     
    }
}

// server.c main
int main(int argc, char *argv[]) {
    ...
    ...
    if(!SetConsoleCtrlHandler(CtrlHandler, TRUE))
    {
        getLastError("SetConsoleCtrlHandler failed");//function written by me
        exit(EXIT_FAILURE);
    }
    ... 
    ...
    //This is how I create child processes (in a for loop)
    STARTUPINFO info;
    GetStartupInfo(&info);
    WSAPROTOCOL_INFO protInfo;
    PROCESS_INFORMATION processInfo;
    if(!CreateProcess("workerProcess.exe",command, NULL, NULL,0,CREATE_NEW_PROCESS_GROUP, NULL, NULL, &info, &processInfo))
    {
        fprintf(stderr, "could not create process.\n");
        return -1;
    }
    ...
    ...
}


//handler for child process(workerProcess.c)
BOOL WINAPI CtrlWorkerHandler( DWORD fdwCtrlType ) 
{ 

    //CTRL_C_EVENT
    if(fdwCtrlType == CTRL_C_EVENT)
    {
        printf("\nCLOSING WORKER\n");
        return FALSE;  
    }
    return TRUE; 
}

//workerProcess.c main
int main(int argc, char *argv[]) {
    ...
    ...
    if(!SetConsoleCtrlHandler(CtrlWorkerHandler, TRUE))
    {
        fprintf(stderr,"setConsoleCtrlHandler failed\n");
        exit(EXIT_FAILURE);
    }
    ...
    ...
}

服务器正确处理CTRL + C信号,GenerateConsoleCtrlEvent函数没有失败,所以我假设它可以将信号发送到与调用进程具有相同 groupid 的所有进程,但不幸的是,该workerProcess.exe进程似乎没有处理CTRL+C从父进程接收到的信号

标签: cwinapiconsolesignalshandler

解决方案


不确定并且现在无法测试,但我试了一下:通过为每个工作进程指定CREATE_NEW_PROCESS_GROUP新进程是新进程组的根进程。)你基本上为每个工作进程创建一个新进程组。

但是,然后调用GenerateConsoleCtrlEvent(0, 0),其中第二个0表示信号是在共享调用进程控制台的所有进程中生成的。似乎是徒劳的。所有工作进程甚至都不在与调用进程相同的进程组中。

CREATE_NEW_PROCESS_GROUP可能,您应该在创建工作进程时删除该标志,或者记住每个工作进程的lpProcessInformation.dwProcessId值并为每个工作进程调用GenerateConsoleCtrlEvent


推荐阅读