perl - 完全创建和杀死进程和子进程
问题描述
我有一个程序,它在 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()
用来创建子进程,每个子进程都system
用来启动一个记事本实例。父进程尝试使用 终止记事本进程taskkill
,并在循环中重复此过程。
该程序在停止之前仅生成(并杀死)64 个记事本实例。很明显,我没有正确处理这些过程,并且周围有一些东西会填满某种表格。
如果我不杀死记事本,仍然有 64 个限制。这可能表明我的清理工作不起作用,我已经杀死了记事本进程,但让孩子活着。
奇怪的是,该system
调用产生了否定结果,但任务管理器或任务管理器$pid
无法识别这些 PID 。taskkill
如何在不达到限制的情况下生成并杀死许多记事本实例?
编辑:按照暴民的想法,这是另一个脚本,但它仍然不会让我产生并杀死超过 64 个记事本:$exit=''; $计数=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
感谢鲍罗丁!)
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;
}
这基本上完成了第一次编辑所做的事情,但不知何故做得更干净 - 可能会像之前的努力那样擦掉孩子的残余物。我仍然很想知道为什么!
每一秒,它都会启动一个子进程,该进程在$pm->start
和之间运行代码$pm->finish
。那个孩子在杀死记事本和死亡之前能活 10 秒,这允许大约 10 个记事本在任何时候存活。最重要的是,在整个程序退出之前,可以有超过 64 个记事本生存和死亡。
我本来想从主进程中杀死每个程序,但是我会知道我什么时候希望它在我启动它之前死掉,这应该可以工作。
更多尝试 - 感谢您迄今为止的帮助,您可以称之为已解决(ish)。
解决方案
对于这样的事情,在 Windows 上,您可能想尝试未充分记录的system 1, LIST
语法。
system(1, @args)
生成一个外部进程并立即返回其进程指示符,而不等待它终止。返回值可以随后在“wait”或“waitpid”中使用。
重要的是,返回值是可以传递给taskkill
(以及 Perl 的waitpid
)的正确进程 id,而不是您从Windows 上的调用中获得的伪进程 id(负数) 。fork
不需要使用fork
这种语法的调用。
$n = "001";
while (-f "datafile$n.txt") {
$pid = system 1, "fancyprogram.exe", "datafile$n.txt";
$n++;
...
}
像这样的模块Forks::Super
在需要管理大量后台进程的脚本中也有很大帮助。它可以帮助的一些方法是限制后台作业的数量(一次只运行你的系统可以合理处理的尽可能多的作业),在后台作业上设置超时,或者在作业上设置优先级或 CPU 亲和性。
推荐阅读
- python - 如何使用 bash 或 Python 将具有多个单页 PDF(蓝图)的文件夹转换为 PNG?
- python - AttributeError:“ca.report”对象没有属性“appliquer”
- angular - 在 ngb-datepicker 中设置日历的开始日期
- django - 我在哪里将我的 Django 根目录放在我的 Linux VPS 中
- laravel - 如何正确处理 Laravel 处理客户订阅已删除事件。?
- webpack - 如何翻译tinymce集成在VUEJS组件中
- c - 相同值的不同 Int 值?
- java - 当应用程序在 Windows 启动时启动时系统托盘图标不活动
- java - 模拟 url.openStream() 应该返回 InputStream
- string - 是否有可能:根据字符串比较选择一个值表单数据表?