c - 如果我在带有 SIGTERM 的 kill() 之后使用 waitpid(),则我的程序不会像预期的那样运行。但是如果我不使用waitpid(),它会起作用吗?
问题描述
我试图关闭一个在子进程上运行的 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, clnt);
if (return_code == NULL) {
printf("%s\n", 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 循环充当导航,我从主方法调用方法。
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,我解决了我的问题。我将在此答案中引用他的内容,以便在有人遇到相同问题时更加明显。
字符 *args[] = {}; 不是有效的 C,因为 C 不支持零长度数组或空初始值设定项。此外,即使您的编译器接受它作为扩展,结果也不会是 execvp 的有效输入,无论被执行的程序可能做什么,因为参数列表必须以空指针终止。
推荐阅读
- c# - 具有复合键的 SortedDictionary:由 1 个属性索引并由另一个属性排序
- java - java.lang.IllegalStateException:另一个 SimpleCache 实例使用该文件夹:
- python - Pandas 将所有列的值连接到一个新的列列表中
- html - 如何使用css flexbox创建水平滚动?
- amazon-web-services - aws 胶水 JDBC 连接
- bash - Git Commit 使用了错误的时区
- android - 如何在 onCreateView 中更改子视图的可见性?
- python - AWS Lambda 函数附加字符作为返回
- javascript - 如果用户存在,则仅使用 Google Auth Provider 进行身份验证
- google-cloud-platform - google cloud platform blob.download_to_file 文件下载位置