问题描述
我正在尝试关闭在子进程上运行的RPC客户端上的接收器,以使其达到最大值。 5秒完成业务。如果在使用waitpid()
时执行此操作以确保子进程在使用SIGTERM
后正常终止,则无法再使用fork()
重新启动接收器。子进程根本不会再使用execvp()打开接收器应用程序,而直接进入应用程序的主菜单。
如果我不使用waitpid()
,而只是将SIGKILL
或SIGTERM
与kill()
函数一起使用,则可以再次重新打开接收器并接收来自调度程序的消息。
示例如何调用方法: 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的有效输入,无论执行程序可能做什么,因为参数列表必须以空指针终止。