如果我在SIGTERM的kill之后使用waitpid,则我的程序将无法正常运行但是,如果我不使用waitpid,它会起作用吗?

问题描述

我正在尝试关闭在子进程上运行的RPC客户端上的接收器,以使其达到最大值。 5秒完成业务。如果在使用waitpid()时执行此操作以确保子进程在使用SIGTERM后正常终止,则无法再使用fork()重新启动接收器。子进程根本不会再使用execvp()打开接收器应用程序,而直接进入应用程序的主菜单。 如果我不使用waitpid(),而只是将SIGKILLSIGTERMkill()函数一起使用,则可以再次重新打开接收器并接收来自调度程序的消息。

示例如何调用方法: sub-> unsub-> sub(如果我在unsub方法中使用waitpid,则此sub不会重新启动RPC_Receiver)

订阅方法

void subscribetodispatcher(CLIENT *clnt) {

    return_code = subscribe_1(NULL,clnt);
    
    if (return_code == NULL) {
        printf("%s\n",PUB_SUB_RET_CODE[UNKNowN_ERROR]);
    } else {
        printf("Subscribe status: %s\n",PUB_SUB_RET_CODE[*return_code]);
    }
    if (*return_code == OK) {
       
        //receivers childprocess
        printf("Starting the message receiver...\n");
        childPID = fork();
        char *args[] = {};

            if (childPID == 0) {
                execvp("./RPC_Receiver",args);
            }
        if(childPID == -1)
            printf("Error beim starten des Receivers. fork() Failed.\n");
    }
}

退订方法

void unsubscribeFromdispatcher(CLIENT *clnt) {

    return_code = unsubscribe_1(NULL,PUB_SUB_RET_CODE[UNKNowN_ERROR]);
    } else {
        printf("Unsubscribe status: %s\n",PUB_SUB_RET_CODE[*return_code]);
    }
    
    if (childPID != -1 && childPID != 0 && *return_code == OK) {

        printf("Closing the message receiver");

        kill(childPID,SIGTERM);

        int childDead = 0;
        int status;
        
        for(int i = 0; !childDead && i < 5; i++){

            printf(".");
            fflush(stdout);
            
            if(waitpid(childPID,&status,WNOHANG) == childPID ) {
                childDead = 1;
                printf("\n");
            }
            sleep(1);
        }
        if(!childDead)
            kill(childPID,SIGKILL);
    }
} 

在作为导航的循环中,我从主方法调用方法

 while (1) {
        menuNavigation(input);

        if (strcmp(input,"sub") == 0) {
            subscribetodispatcher(clnt);
        } else if (strcmp(input,"unsub") == 0) {
            unsubscribeFromdispatcher(clnt);
        } else if (strcmp(input,"publish") == 0) {
            sendMessage(clnt);
        } else if (strcmp(input,"topic") == 0) {
            setTopic(clnt);

        } else if (strcmp(input,"exit") == 0) {
            printf("closing the application.\n");
            unsubscribeFromdispatcher(clnt);
            free(input);
            clnt_destroy(clnt);
            exit(1);
        }
        memset(input,'\0',sizeof(&input));
    }

解决方法

由于@JohnBollinger,我解决了我的问题。我将在此答案中引用他的内容,以便在有人遇到相同问题时更加明显。

char * args [] = {};是无效的C,因为C不支持零长度数组或空的初始化程序。而且,即使您的编译器接受该扩展名,结果也将不是execvp的有效输入,无论执行程序可能做什么,因为参数列表必须以空指针终止。