perl多任务问题
我已经完成了我以前使用perl线程的多线程程序,它可以在我的系统上运行。问题是,在某些需要运行线程的系统上,线程支持没有编译成perl,我无法安装其他软件包。因此,我需要使用线程以外的东西,我正在将代码移到使用fork()。这在我的windows系统上可以启动子任务 有几个问题:perl多任务问题,perl,multithreading,parallel-processing,multitasking,Perl,Multithreading,Parallel Processing,Multitasking,我已经完成了我以前使用perl线程的多线程程序,它可以在我的系统上运行。问题是,在某些需要运行线程的系统上,线程支持没有编译成perl,我无法安装其他软件包。因此,我需要使用线程以外的东西,我正在将代码移到使用fork()。这在我的windows系统上可以启动子任务 有几个问题: 如何确定子进程何时退出?当线程数低于某个值时,我创建了新线程,我需要跟踪有多少线程正在运行。对于进程,我如何知道一个何时退出,以便跟踪当时存在多少个进程,在创建一个进程时递增计数器,在退出时递减计数器 当父进程在子进程
#!/usr/bin/perl
use strict;
use warnings;
use POSIX ":sys_wait_h";
my $max_children = 3;
my %work = map { $_ => 1 } 1 .. 9;
my @work = keys %work;
my %pids;
while (%work) {
#while there are still empty slots
while (@work and keys %pids < $max_children) {
#get some work for the child to do
my $work = shift @work;
die "could not fork" unless defined(my $pid = fork);
#parent
if ($pid) {
$pids{$pid} = 1;
next;
}
#child
print "$$ doing work $work\n";
sleep 1;
print "$$ done doing work $work";
exit $work;
}
my $pid = waitpid -1, WNOHANG;
if ($pid > 0) {
delete $pids{$pid};
my $rc = $? >> 8; #get the exit status
print "saw $pid was done with $rc\n";
delete $work{$rc};
print "work left: ", join(", ", sort keys %work), "\n";
}
select undef, undef, undef, .25;
}
#/usr/bin/perl
严格使用;
使用警告;
使用POSIX“:sys_wait_h”;
我的$max_children=3;
我的%work=map{$\=>1}1。。9;
我的@work=键%work;
我的%pids;
同时(工作百分比){
#当仍有空插槽时
while(@work and key%pids<$max_children){
#给孩子找些工作做
我的$work=shift@work;
除非定义(my$pid=fork),否则die“无法分叉”;
#母公司
如果($pid){
$pid{$pid}=1;
下一个
}
#孩子
打印“$$doing work$work\n”;
睡眠1;
打印“$$done doing work$work”;
退出$work;
}
my$pid=waitpid-1,WNOHANG;
如果($pid>0){
删除$pid{$pid};
my$rc=$?>>8;#获取退出状态
打印“saw$pid是用$rc完成的\n”;
删除$work{$rc};
打印“剩余工时:”,连接(“,”,排序键%work),“\n”;
}
选择未定义、未定义、未定义、.25;
}
典型用法:
use POSIX ':sys_wait_h'; # for &WNOHANG
# how to create a new background process
$pid = fork();
if (!defined $pid) { die "fork() failed!" }
if ($pid == 0) { # child
# ... do stuff in background ...
exit 0; # don't forget to exit or die from the child process
}
# else this is the parent, $pid contains process id of child process
# ... do stuff in foreground ...
# how to tell if a process is finished
# also see perldoc perlipc
$pid = waitpid -1, 0; # blocking wait for any process
$pid = wait; # blocking wait for any process
$pid = waitpid $mypid, 0; # blocking wait for process $mypid
# after blocking wait/waitpid
if ($pid == -1) {
print "All child processes are finished.\n";
} else {
print "Process $pid is finished.\n";
print "The exit status of process $pid was $?\n";
}
$pid = waitpid -1, &WNOHANG; # non-blocking wait for any process
$pid = waitpid $mypid, 0; # blocking wait for process $mypid
if ($pid == -1) {
print "No child processes have finished since last wait/waitpid call.\n";
} else {
print "Process $pid is finished.\n";
print "The exit status of process $pid was $?\n";
}
# terminating a process - see perldoc -f kill or perldoc perlipc
# this can be flaky on Windows
kill 'INT', $pid; # send SIGINT to process $pid
血淋淋的细节在、、和中。perlipc
中关于为SIGCHLD
事件设置处理程序的内容应该特别有用,尽管Windows不支持
在Unix和Windows上,跨越分叉进程的I/O通常是安全的。文件描述符是共享的,所以对于这样的东西
open X, ">", $file;
if (fork() == 0) { # in child
print X "Child\n";
close X;
exit 0;
}
# in parent
sleep 1;
print X "Parent\n";
close X;
子进程和父进程都将成功写入同一个文件(不过要注意输出缓冲)。更像是一种解决方法,但您可以在进程启动时写入文件,然后在退出时删除该文件或类似的内容。。。有一个主脚本来监视这些文件等等。。。