从 C++ 暂停和恢复 shell 进程
Pausing and resuming a shell process from C++
在 C++ 中,我希望提交一个进程,暂停、恢复和停止它。为此,我首先使用以下函数在后台 运行 一个 shell 进程并保存关联的 PID。我在 this post 找到了函数(并且只删除了标准输入和输出)。
int system2(const char * command)
{
int p_stdin[2];
int p_stdout[2];
int pid;
if (pipe(p_stdin) == -1)
return -1;
if (pipe(p_stdout) == -1) {
close(p_stdin[0]);
close(p_stdin[1]);
return -1;
}
pid = fork();
if (pid < 0) {
close(p_stdin[0]);
close(p_stdin[1]);
close(p_stdout[0]);
close(p_stdout[1]);
return pid;
} else if (pid == 0) {
close(p_stdin[1]);
dup2(p_stdin[0], 0);
close(p_stdout[0]);
dup2(p_stdout[1], 1);
dup2(::open("/dev/null", O_RDONLY), 2);
/// Close all other descriptors for the safety sake.
for (int i = 3; i < 4096; ++i)
::close(i);
setsid();
execl("/bin/sh", "sh", "-c", command, NULL);
_exit(1);
}
close(p_stdin[0]);
close(p_stdout[1]);
return pid;
}
然后,我正在使用 kill
函数来暂停、恢复和停止进程,但它没有像我预期的那样工作。这是一个例子:
int main()
{
// The process prints on file allowing me to figure out whether the process is paused / stopped, or is running
const char * command = "for i in {1..1000}; do echo $i >> /Users/remi/test/data.txt; sleep 1s;done";
// Run the command and record pid
auto pid = system2(command);
std::cout << "pid = " << pid << "\n";
// with this pid, I could ensure that `ps -p <pid>` returns the correct command
std::cout << "process should be running!\n"; // It is!
// wait
std::this_thread::sleep_for(std::chrono::seconds(10));
// pause
kill(pid, SIGTSTP);
std::cout << "process should be paused!\n"; // But it is not!
// wait
std::this_thread::sleep_for(std::chrono::seconds(10));
// resume process
kill(pid, SIGCONT);
std::cout << "process should be running!\n"; // Sure, it is as it has never been stopped
// wait
std::this_thread::sleep_for(std::chrono::seconds(10));
// Kill process
kill(pid, SIGSTOP);
std::cout << "process should be stopped!\n"; // That worked!
// wait
std::this_thread::sleep_for(std::chrono::seconds(10));
}
能否请您帮我弄清楚如何修复此代码以确保进程按预期停止和恢复。
仅供参考,我使用的是 macOS,希望该解决方案适用于任何 POSIX 系统。
请注意,SIGTSTP
和 SIGSTOP
信号实际上都在暂停进程。第一个可以被过程忽略,但后者不能。如果您希望暂停该过程,无论使用什么 SIGSTOP
.
要终止进程,请使用 SIGTERM
或 SIGKILL
。
在 C++ 中,我希望提交一个进程,暂停、恢复和停止它。为此,我首先使用以下函数在后台 运行 一个 shell 进程并保存关联的 PID。我在 this post 找到了函数(并且只删除了标准输入和输出)。
int system2(const char * command)
{
int p_stdin[2];
int p_stdout[2];
int pid;
if (pipe(p_stdin) == -1)
return -1;
if (pipe(p_stdout) == -1) {
close(p_stdin[0]);
close(p_stdin[1]);
return -1;
}
pid = fork();
if (pid < 0) {
close(p_stdin[0]);
close(p_stdin[1]);
close(p_stdout[0]);
close(p_stdout[1]);
return pid;
} else if (pid == 0) {
close(p_stdin[1]);
dup2(p_stdin[0], 0);
close(p_stdout[0]);
dup2(p_stdout[1], 1);
dup2(::open("/dev/null", O_RDONLY), 2);
/// Close all other descriptors for the safety sake.
for (int i = 3; i < 4096; ++i)
::close(i);
setsid();
execl("/bin/sh", "sh", "-c", command, NULL);
_exit(1);
}
close(p_stdin[0]);
close(p_stdout[1]);
return pid;
}
然后,我正在使用 kill
函数来暂停、恢复和停止进程,但它没有像我预期的那样工作。这是一个例子:
int main()
{
// The process prints on file allowing me to figure out whether the process is paused / stopped, or is running
const char * command = "for i in {1..1000}; do echo $i >> /Users/remi/test/data.txt; sleep 1s;done";
// Run the command and record pid
auto pid = system2(command);
std::cout << "pid = " << pid << "\n";
// with this pid, I could ensure that `ps -p <pid>` returns the correct command
std::cout << "process should be running!\n"; // It is!
// wait
std::this_thread::sleep_for(std::chrono::seconds(10));
// pause
kill(pid, SIGTSTP);
std::cout << "process should be paused!\n"; // But it is not!
// wait
std::this_thread::sleep_for(std::chrono::seconds(10));
// resume process
kill(pid, SIGCONT);
std::cout << "process should be running!\n"; // Sure, it is as it has never been stopped
// wait
std::this_thread::sleep_for(std::chrono::seconds(10));
// Kill process
kill(pid, SIGSTOP);
std::cout << "process should be stopped!\n"; // That worked!
// wait
std::this_thread::sleep_for(std::chrono::seconds(10));
}
能否请您帮我弄清楚如何修复此代码以确保进程按预期停止和恢复。
仅供参考,我使用的是 macOS,希望该解决方案适用于任何 POSIX 系统。
请注意,SIGTSTP
和 SIGSTOP
信号实际上都在暂停进程。第一个可以被过程忽略,但后者不能。如果您希望暂停该过程,无论使用什么 SIGSTOP
.
要终止进程,请使用 SIGTERM
或 SIGKILL
。