我如何暂停 child 进程并重置它
how i can suspend child process and reset it
我正在 shell 中创建一个带有 fork 的 child 进程,并分配这个 child 进程来执行命令,例如:"ls -lR /",使用 'execve()' 就像你在我的代码中看到的那样,当我收到 SIGTSTP 时,我想用 kill(child_process, SIGTSTP)
停止这个 child 进程,当你键入 "fg" 命令时,我必须重置这个 child 使用 kill(child_process, SIGCONT)
运行,问题是 wait(&status)
在我收到 SIGTSTP 之后 return 仍在等待 child 结束,
-- 那么我该怎么做呢??
#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()
将等待 child 进程被 终止 ,这意味着进程必须已经退出,例如从 SIGKILL 或 SIGSEGV。您正在尝试等待进程停止,这不是一回事。停止一个进程只是暂停它,它允许它稍后继续。它不会退出。
您需要将 WUNTRACED
标志与 waitpid()
一起使用,以等待 child 个进程终止 或停止 。如waitpid(child_pid, &status, WUNTRACED)
或waitpid(-1, &status, WUNTRACED)
.
还有一个与此相关的缺陷。 WIFSIGNALLED()
和 WTERMSIG()
也仅适用于由信号终止的处理。您应该改用 WIFSTOPPED()
和 WSTOPSIG()
来检测 child 是否已停止。
另请注意:
SIGSTOP
也可以停止一个进程。
- 您可能会在设置信号处理程序后随时收到
SIGTSTP
,这可能是在 child_pid
被赋值之前。
wait()
如果您的进程被信号中断,朋友们可以 return -1 将 errno
设置为 EINTR
。
我正在 shell 中创建一个带有 fork 的 child 进程,并分配这个 child 进程来执行命令,例如:"ls -lR /",使用 'execve()' 就像你在我的代码中看到的那样,当我收到 SIGTSTP 时,我想用 kill(child_process, SIGTSTP)
停止这个 child 进程,当你键入 "fg" 命令时,我必须重置这个 child 使用 kill(child_process, SIGCONT)
运行,问题是 wait(&status)
在我收到 SIGTSTP 之后 return 仍在等待 child 结束,
-- 那么我该怎么做呢??
#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()
将等待 child 进程被 终止 ,这意味着进程必须已经退出,例如从 SIGKILL 或 SIGSEGV。您正在尝试等待进程停止,这不是一回事。停止一个进程只是暂停它,它允许它稍后继续。它不会退出。
您需要将 WUNTRACED
标志与 waitpid()
一起使用,以等待 child 个进程终止 或停止 。如waitpid(child_pid, &status, WUNTRACED)
或waitpid(-1, &status, WUNTRACED)
.
还有一个与此相关的缺陷。 WIFSIGNALLED()
和 WTERMSIG()
也仅适用于由信号终止的处理。您应该改用 WIFSTOPPED()
和 WSTOPSIG()
来检测 child 是否已停止。
另请注意:
SIGSTOP
也可以停止一个进程。- 您可能会在设置信号处理程序后随时收到
SIGTSTP
,这可能是在child_pid
被赋值之前。 wait()
如果您的进程被信号中断,朋友们可以 return -1 将errno
设置为EINTR
。