- r - 以节省内存的方式增长 data.frame
- ruby-on-rails - ruby/ruby on rails 内存泄漏检测
- android - 无法解析导入android.support.v7.app
- UNIX 域套接字与共享内存(映射文件)
在下面的脚本中,我试图弄清楚 waitpid
是如何工作的,但它不会等待 ssh
进程退出。 done
立即打印,而不是在 ssh
进程存在之后打印。
问题
如何让 waitpid
仅在我给它的 pid 退出时继续?
#!/usr/bin/perl
use strict;
use warnings;
use Parallel::ForkManager;
use POSIX ":sys_wait_h";
my $pm = Parallel::ForkManager->new(5);
my $pid = $pm->start;
my $p = $pid;
if (!$pid) {
system("ssh 10.10.47.47 sleep 10");
$pm->finish;
}
$p = qx(/usr/bin/pgrep -P $p);
print "ssh pid is $p\n";
my $kid;
do {
$kid = waitpid($p, 0);
} while $kid > 0;
print "done\n";
我也试过
while (1) {
$p = kill 0, $p;
print "x";
sleep 1 if $p;
print "*";
last unless $p;
}
但由于某种原因它甚至没有到达第一个 print
并且永远不会退出。
最佳答案
wait
系列函数仅适用于子进程,甚至 waitpid
。 sleep 过程不是你的 child ,而是你 child 的 child 。这是因为 system
本质上是 fork
+ exec
。通过使用 Parallel::ForkManager + 系统,您正在 fork ,然后再次 fork ,然后执行 sleep 。
既然你已经 fork 了,你应该使用 exec。这具有不需要调用 pgrep 的额外优势,并且它是时间问题(即,父级可能会在子级执行系统之前调用 pgrep)。
my $pm = Parallel::ForkManager->new(5);
my $pid = $pm->start;
my $p = $pid;
if (!$pid) {
no warnings; # no warnings "exec" is not working
exec("sleep 10");
$pm->finish;
}
print "sleep pid is $p\n";
waitpid($p, 0);
为简单起见,它现在使用 sleep 。必须禁止来自 Perl 的警告“不太可能达到语句”,因为 Perl 没有意识到 $pm->start
已经 fork 。这应该是 no warnings "exec"
但这不起作用,所以我不得不将它们全部抑制。
关于linux - 为什么waitpid不等待进程退出呢?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27677077/
我正在使用 C 语言开发一个基于 ncurses 的文件管理器。问题是一些子进程可能需要一些时间才能完成,直到发生这种情况,它会因为 waitpid 而卡住。 我不能使用 WNOHANG 标志,因为下
我写了代码来按顺序打印pid parent->g3->c2->g1->g2->c1 . 所以我用了 wait() , 和 waitpid() .但我失败了。 所以我写了“完成”代码来知道什么是问题。
#include #include #include int main() { int status; int pid = fork();assigned to variab
我的管道有问题。我浏览了这些主题,但没有找到任何可以解决我的问题的内容。 我的管道工作正常,但我想知道我的 child 何时终止。所以我想用waitpid来检查我的 child 。但这是行不通的。 我
我有一个函数可以启动一个进程,然后返回标准输出和退出代码。但是我注意到它声称每个进程都返回 1 的退出代码。我控制被调用的可执行文件并将它打印到标准输出退出代码,所以我已经确认当它“失败”时,它实际上
我需要在 Linux 下使用 C 模拟以下 bash 命令(使用 fork、exec、kill、signal、wait、waitpid、dup2、open、sleep、pipe 等)。 [0] ech
我有一个简单的功能 - 它的目的是在覆盖之前将文件复制到 .old。因为我很懒惰(这里的答案是这样建议的)我 fork 并使用 cp 来完成这项工作。 然后我调用 waitpid 并检查返回码。 调用
我正在使用 waitpid(2) 检查和标记作业控制程序的进程状态。我正在使用 WUNTRACED 选项,以在作业控制程序中捕获有用的信号,如 SIGTSTP。 问题是,当 CTRL-Z (SIGTS
我在我的代码中执行以下步骤: fork() execv 在子进程中运行一个外部脚本 在父进程中: While( waitpid(..., WNOHANG) == 0) { //Send
我想知道你是否可以更改参数waitpid() 目前我需要连续变量输出 ( 0.50 ) 来打印。但是,考虑到 waitpid() 在我尝试打印输出时只接受整数,它会给我 0。不确定如何解决这个问题,或
我试图从父进程访问 fork 子进程的退出状态,但我得到了奇怪的答案。有时,我得到 256,有时我得到一个负数,这取决于我指定的是 &status 还是仅指定 status。我知道我真的很接近。有人可
这个问题不太可能帮助任何 future 的访问者;它只与一个小的地理区域、一个特定的时间点或一个非常狭窄的情况相关,这些情况并不普遍适用于互联网的全局受众。为了帮助使这个问题更广泛地适用,visit
我有一个父进程和一个子进程通过管道进行通信。 parent 写, child 读。而且,一旦 child 读完了,它就会对读过的数据做一些处理。我需要确保父级等到子级完成处理此数据(而不是终止)。 我
我正在使用 execv 启动一个进程并让它写入一个文件。我同时启动了一个线程来监视文件,以便它的大小不超过使用 stat.st_size 的特定限制。现在,当达到限制时,我为子进程 waitpid ,
我对 waitpid 参数有疑问。我应该在 p[0] 完成后开始 p[1](进程 1)。 这是 p0 的开始: if(p[0] == 0){ process(0,1); //(process,
如果我fork一个子进程,子进程在父进程调用waitpid之前退出,那么就是waitpid #include #include #include #include #include int
来自现有问题 here ,有人给出了这个示例代码: int status; child_pid = fork(); if (child_pid == 0) { // in child; do
如果发生崩溃,我们使用以下函数转储堆栈以获取有关崩溃的更多信息: static void dumpStack() { char buf[64]; pid_t p
我创建了一个模仿 std::thread 的简单 Process 类。它应该只在 linux 上工作。 struct Process { Process(/*...*/) { /* fork
我对 waitpid 函数有点困惑: int main(int argc, char** argv) { if (pid_t pid = fork()) { setpgid(p
我是一名优秀的程序员,十分优秀!