完全创建和终止进程以及 child 个进程
Creating and killing processes and child processes completely
我有一个程序 Windows 从命令提示符使用这样的命令
C:\Users\AndyI> ./myprogram.exe datafile.txt
我想使用 Perl 程序创建许多 datafile.txt
的实例(例如,datafile.001.txt
、datafile.002.txt
等)并调用 myprogram.exe
来处理它们并行。
这个通用程序说明了我遇到的问题
$exit = '';
$count = 0;
while ( $exit eq '' ) {
$pid = fork();
if ( $pid == 0 ) { # if this is a child process
$exit = 'yes';
system 'notepad.exe'; # open an instance of Notepad
}
else {
system("taskkill /im notepad.exe /f"); # Kill all instances
$count++;
print "$count instances\n";
}
if ( $count > 500 ) { # In case of infinite loop
$exit = 'yes';
}
}
sleep 100; # So I have time to read the output
我正在使用 fork()
创建 child 个进程,每个 child 使用 system
启动一个记事本实例。 parent 进程试图用 taskkill
终止记事本进程,并循环重复。
该程序在停止前仅生成(并终止)了 64 个记事本实例。很明显,我没有正确处理这些过程,并且周围有一些位填充了某种 table.
如果我不杀死记事本,仍然有 64 个限制。这可能表明我的清理工作不起作用,我已经杀死了记事本进程,但让 child 存活。
奇怪的是 system
调用产生一个负值 $pid
但这些 PID 无法被 taskkill
或任务管理器识别。
如何在不达到限制的情况下生成和终止许多记事本实例?
编辑:按照暴民的想法,这是另一个脚本,但它仍然不会让我产生并杀死超过 64 个记事本:
$出口='';
$count=0;
while($exit eq ''){
$pid=system 1,'notepad.exe'; # open an instance of Notepad
print "$pid\n";
sleep 1; # Slows it down for easy viewing - not necessary
system("taskkill /pid $pid /f"); # Kill by PID
$count++;
print"$count instances\n";
if($count>100){ # in case of infinite loop!
$exit='yes';
}
}
sleep 100; # so I have time to read the output!
有什么想法吗?我还没有找到 waitpid 或 wait 的用途 - 你能澄清一下你的意思吗?我需要杀戮,而不是等待。 (同样,不是搜索引擎的短语!)。
EDIT2:Parallel::ForkManager
(感谢 Borodin!)
use Parallel::ForkManager;
my $pm=Parallel::ForkManager->new(20); # maximum number of child processes at any one time
PROGS:
for(my $i=1;$i<=100;$i++){
print"$i\n";
sleep 1;
$pm->start and next PROGS;
my $pid=system 1,'notepad.exe';
sleep 10;
system("taskkill /pid $pid /f");
$pm->finish;
}
这基本上完成了第一次编辑所做的工作,但不知何故做得更干净 - 也许擦掉了早期工作所做的 child 的残余。我仍然很想知道为什么!
每一秒,它都会启动一个 child 进程,运行 $pm->start
和 $pm->finish
之间的代码。 child 在杀死记事本并死亡之前存活了 10 秒,这允许大约 10 个记事本在任何时候存活。他们最重要的是,在整个程序退出之前,超过 64 个记事本可以生存和死亡。
我本来想从主进程中终止每个程序,但我知道我希望它在启动之前就结束,这应该可行。
还有很多要尝试的 - 感谢到目前为止的帮助,你可以称之为已解决(ish)。
对于这样的事情,在 Windows 上,您可能想尝试 underdocumented system 1, LIST
syntax。
system(1, @args)
spawns an external process and immediately returns its process designator, without waiting for it to terminate. Return value
may be used subsequently in "wait" or "waitpid".
重要的是,return 值是一个正确的进程 ID,可以传递给 taskkill
(以及 Perl 的 waitpid
),而不是 伪- 您从 Windows 上的 fork
调用中获得的进程 ID(负数)。无需使用此语法的 fork
调用。
$n = "001";
while (-f "datafile$n.txt") {
$pid = system 1, "fancyprogram.exe", "datafile$n.txt";
$n++;
...
}
像 Forks::Super
这样的模块也可以在需要管理大量后台进程的脚本中提供很大帮助。它可以帮助的一些方法是限制后台作业的数量(运行 一次只能处理系统可以合理处理的作业数)、设置后台作业超时或设置优先级或 CPU 对工作的亲和力。
我有一个程序 Windows 从命令提示符使用这样的命令
C:\Users\AndyI> ./myprogram.exe datafile.txt
我想使用 Perl 程序创建许多 datafile.txt
的实例(例如,datafile.001.txt
、datafile.002.txt
等)并调用 myprogram.exe
来处理它们并行。
这个通用程序说明了我遇到的问题
$exit = '';
$count = 0;
while ( $exit eq '' ) {
$pid = fork();
if ( $pid == 0 ) { # if this is a child process
$exit = 'yes';
system 'notepad.exe'; # open an instance of Notepad
}
else {
system("taskkill /im notepad.exe /f"); # Kill all instances
$count++;
print "$count instances\n";
}
if ( $count > 500 ) { # In case of infinite loop
$exit = 'yes';
}
}
sleep 100; # So I have time to read the output
我正在使用 fork()
创建 child 个进程,每个 child 使用 system
启动一个记事本实例。 parent 进程试图用 taskkill
终止记事本进程,并循环重复。
该程序在停止前仅生成(并终止)了 64 个记事本实例。很明显,我没有正确处理这些过程,并且周围有一些位填充了某种 table.
如果我不杀死记事本,仍然有 64 个限制。这可能表明我的清理工作不起作用,我已经杀死了记事本进程,但让 child 存活。
奇怪的是 system
调用产生一个负值 $pid
但这些 PID 无法被 taskkill
或任务管理器识别。
如何在不达到限制的情况下生成和终止许多记事本实例?
编辑:按照暴民的想法,这是另一个脚本,但它仍然不会让我产生并杀死超过 64 个记事本: $出口=''; $count=0;
while($exit eq ''){
$pid=system 1,'notepad.exe'; # open an instance of Notepad
print "$pid\n";
sleep 1; # Slows it down for easy viewing - not necessary
system("taskkill /pid $pid /f"); # Kill by PID
$count++;
print"$count instances\n";
if($count>100){ # in case of infinite loop!
$exit='yes';
}
}
sleep 100; # so I have time to read the output!
有什么想法吗?我还没有找到 waitpid 或 wait 的用途 - 你能澄清一下你的意思吗?我需要杀戮,而不是等待。 (同样,不是搜索引擎的短语!)。
EDIT2:Parallel::ForkManager
(感谢 Borodin!)
use Parallel::ForkManager;
my $pm=Parallel::ForkManager->new(20); # maximum number of child processes at any one time
PROGS:
for(my $i=1;$i<=100;$i++){
print"$i\n";
sleep 1;
$pm->start and next PROGS;
my $pid=system 1,'notepad.exe';
sleep 10;
system("taskkill /pid $pid /f");
$pm->finish;
}
这基本上完成了第一次编辑所做的工作,但不知何故做得更干净 - 也许擦掉了早期工作所做的 child 的残余。我仍然很想知道为什么!
每一秒,它都会启动一个 child 进程,运行 $pm->start
和 $pm->finish
之间的代码。 child 在杀死记事本并死亡之前存活了 10 秒,这允许大约 10 个记事本在任何时候存活。他们最重要的是,在整个程序退出之前,超过 64 个记事本可以生存和死亡。
我本来想从主进程中终止每个程序,但我知道我希望它在启动之前就结束,这应该可行。
还有很多要尝试的 - 感谢到目前为止的帮助,你可以称之为已解决(ish)。
对于这样的事情,在 Windows 上,您可能想尝试 underdocumented system 1, LIST
syntax。
system(1, @args)
spawns an external process and immediately returns its process designator, without waiting for it to terminate. Return value may be used subsequently in "wait" or "waitpid".
重要的是,return 值是一个正确的进程 ID,可以传递给 taskkill
(以及 Perl 的 waitpid
),而不是 伪- 您从 Windows 上的 fork
调用中获得的进程 ID(负数)。无需使用此语法的 fork
调用。
$n = "001";
while (-f "datafile$n.txt") {
$pid = system 1, "fancyprogram.exe", "datafile$n.txt";
$n++;
...
}
像 Forks::Super
这样的模块也可以在需要管理大量后台进程的脚本中提供很大帮助。它可以帮助的一些方法是限制后台作业的数量(运行 一次只能处理系统可以合理处理的作业数)、设置后台作业超时或设置优先级或 CPU 对工作的亲和力。