【发布时间】:2021-12-14 23:39:20
【问题描述】:
我正在创建自己的 shell(如 bash),并且我有一个调用 execv 函数并传入特定进程 pid 以终止的函数。我基本上运行一个睡眠命令 10 秒,中途我想杀死它。但是我的 kill 命令似乎不起作用。有没有人知道我该如何解决它?
下面是execv相关的函数
void run_execv(char *path, char *args[])
{
int result = execv(path, args);
}
void kill_process(char *target_pid)
{
char *bin_path = "/bin/kill";
char *args[] = {bin_path, "-15", target_pid, NULL};
run_execv(bin_path, args);
}
void ps()
{
char *bin_path = "/bin/ps";
char *args[] = {bin_path, NULL};
run_execv(bin_path, args);
}
而kill_process函数的调用如下图所示。基本上我将 kill 命令称为子进程。
else if (strncmp(shellInput, "pkill", strlen("pkill")) == 0 || strncmp(shellInput, "kill", strlen("kill")) == 0)
{
char *target_pid = strtok(NULL, " \n");
int childStatus;
pid_t spawnPid = fork();
switch (spawnPid)
{
case -1:
perror("fork()\n");
exit(1);
break;
case 0:
// This is the child process where we will call the ls function
kill_process(target_pid);
perror("execv");
exit(2);
break;
default:
// This is the parent process that takes control back after child process finishes.
spawnPid = waitpid(spawnPid, &childStatus, 0);
printf("CHILD STATUS: %d\n", childStatus);
processStatus = childStatus;
break;
}
即使在杀死该睡眠进程之后,当我检查当前使用 ps 运行的进程时,它仍然会出现。请参阅下面的屏幕截图以了解相同的执行情况。
~/Desktop/OSU/CS-344 (Operating Systems)/assignment3(main*) » ./a.out sampai@sams-mbp-2
: ps
PID TTY TIME CMD
25223 ttys003 0:06.24 /bin/zsh -l
41134 ttys003 0:00.00 ./a.out
32018 ttys004 0:01.49 -zsh
30707 ttys005 0:00.14 /bin/zsh --login -i
: sleep 30 &
background pid is 41143
: ps
PID TTY TIME CMD
25223 ttys003 0:06.24 /bin/zsh -l
41134 ttys003 0:00.00 ./a.out
41143 ttys003 0:00.00 sleep 30
32018 ttys004 0:01.49 -zsh
30707 ttys005 0:00.14 /bin/zsh --login -i
: kill 41143
CHILD STATUS: 0
: ps
PID TTY TIME CMD
25223 ttys003 0:06.24 /bin/zsh -l
41134 ttys003 0:00.00 ./a.out
41143 ttys003 0:00.00 (sleep)
32018 ttys004 0:01.49 -zsh
30707 ttys005 0:00.14 /bin/zsh --login -i
:
【问题讨论】:
-
请将输出显示为文本而不是图像。否则,其他人很难从您的输出中查看和复制。
(sleep)方括号表示该进程已终止但未收割(即它是僵尸进程)。你需要在杀死它后在睡眠进程id上调用waitpid。 -
好的,感谢您让我知道这一点!这不是我在 switch 语句的默认部分所做的吗? spawnPid = waitpid(spawnPid, &childStatus, 0);
-
不,您正在等待正在执行杀戮的进程,而不是正在被杀死的进程。
-
请注意,您根本不需要分叉。直接调用
kill函数即可。 -
阅读手册。您可能缺少包含。
标签: c linux bash process operating-system