我正在 shell 中使用 fork 创建一个子进程,并分配该子进程来执行 cmd,例如:“ls -lR/”,使用“execve()”,就像您在我的代码中看到的那样,当我收到 SIGTSTP,我想用 kill(child_process, SIGTSTP)
停止这个子进程,当你输入“fg”命令时,我必须用 kill(child_process, SIGCONT) 重置这个子进程
,问题是 wait(&status)
在我收到 SIGTSTP 后永远不会返回仍在等待子进程结束,
——那么我该怎么做呢??
#include <signal.h>
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>
int child_pid;
int parn_pid;
void func1(int sig)
{
kill(child_pid, SIGTSTP);
}
int main()
{
int sig;
int status;
char *argv[] = {"ls", "-lR", "/", NULL};
signal(SIGTSTP, func1);
child_pid = fork();
if (child_pid == 0)
{
child_pid = getpid();
execve("/bin/ls", argv, NULL);
exit (1);
}
else
{
parn_pid = getpid();
waitpid(child_pid, &status, WUNTRACED);
printf("\nsuspended\n");
if (WIFSTOPPED(status))
{
sleep(2);
kill(child_pid, SIGCONT);
wait(&status);
}
}
return (0);
}
最佳答案
您需要使用waitpid()
而不是wait()
。使用 wait()
将等待子进程终止,这意味着进程必须已退出,例如从 SIGKILL 或 SIGSEGV 退出。您正在尝试等待进程停止,这不是一回事。停止进程只是暂停它,并允许稍后继续。它不会退出。
您需要将 WUNTRACED
标志与 waitpid()
结合使用来等待子进程终止或停止。例如 waitpid(child_pid, &status, WUNTRACED)
或 waitpid(-1, &status, WUNTRACED)
。
还有另一个与此相关的缺陷。 WIFSIGNALLED()
和 WTERMSIG()
也仅适用于由信号终止的处理。您应该使用 WIFSTOPPED()
和 WSTOPSIG()
来检测子进程是否已停止。
另请注意:
SIGSTOP
也可以停止进程。- 设置信号处理程序后,您可能随时收到
SIGTSTP
,这可能是在为child_pid
赋值之前。 wait()
如果您的进程被信号中断,则可以返回 -1,并将errno
设置为EINTR
。
关于c - 我如何暂停子进程并重置它,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59184584/