c - 在C中使用父进程杀死后台进程
问题描述
我的主要功能中有以下代码
pid_t pid;
pid = fork(); //Two processes are made
if (pid > 0 && runBGflag==0) //Parent process. Waits for child termination and prints exit status
{
int status;
if (waitpid(pid, &status, 0) == pid && WIFEXITED(status))
{
printf("Exitstatus [");
for (int i = 0; i < noOfTokens; i++)
{
printf("%s ", commands[i]);
}
printf("\b] = %d\n", WEXITSTATUS(status));
}
}
else if (pid == 0) //Child process. Executes commands and prints error if something unexpected happened
{
if (runBGflag==1) insertElement(getpid(),ptr);
execvp(commands[0], commands);
printf ("exec: %s\n", strerror(errno));
exit(1);
}
简而言之,创建了一个子进程,如果设置了 runBackGround 标志,则父进程不会等待子进程退出,而是继续运行。如果创建了后台进程,则后台进程的 PID 存储在列表中。稍后,将调用此函数
void delete_zombies(void)
{
pid_t kidpid;
int status;
char buffer[1337];
while ((kidpid = waitpid(-1, &status, WNOHANG)) > 0)
{
removeElement(kidpid,buffer,1337);
printf("Child %ld terminated\n", kidpid);
printf("its command was %s\n",buffer);
}
}
此函数仅检查是否有任何子进程已死亡,并在这种情况下将其删除。然后它将在列表中搜索孩子的 PID,将其删除并打印出来。
问题是,delete_zombies 函数会发现一个子进程已经死亡,然后会尝试将其从列表中删除,但它只会找到一个空列表,就好像子进程从未将其 PID 插入到列表中一样。
这真的很奇怪,因为 delete_zombies 只找到一个死子进程,当有一个设置了背景标志的创建时,所以我们知道 insertElement 必须被调用,但奇怪的是,当父进程在列表中检查时什么都没有
原因是子进程和父进程有单独的列表,还是 PID 可能是错误的?
解决方案
推荐阅读
- sparql - 如何在 SPARQL 中执行“过滤器(x IN(...))”?
- symfony - Symfony 如何使用 SonataAdmin 更改用户密码?
- sql - SQL:按选定列对记录进行分组
- typescript - 打字稿节点找不到模块
- ios - 在静态函数闭包上更改 UIButton 属性
- android - 无法解决android中的flutter firestore
- mysql - 如何模拟mysql数据库?
- sql-server - SSIS 表达式生成器从年份返回 YY
- sql - 生成范围小时数和范围号 SQL/HQL
- sql-server - MSSQL:在创建表中添加唯一约束并允许 NULL