关于perl的多进程,大家可能马上会想到这个模块。但是今天我们试着自己动手写一个类似的框架:)
该多进程开发模型从开源服务器框架发展而来,核心思路是父进程监控子进程的状态并负责回收,子进程负责任务的执行。当前预先可以设置子进程并发数目的上限值。如需要涉及到进程间的通信,可以通过建立管道pipe的方式,让子进程在结束前将数据通过共享管道写入,待父进程适时读取即可。
本人在工作中进程遇到这样的场景,如从DB取若干任务,收包等等(不停的取/收),为了保证效率,一般都采取并发执行;使用脚本主要为了轻量级,易部署。这种场景下很适合用这种watcher-worker模式。perl代码如下:
1 #!/usr/bin/perl -w 2 3 #author:pandaychen 4 #date:2015-04-01 5 #info:实现一个简单的多进程框架 6 7 use strict; 8 use warnings; 9 use POSIX ":sys_wait_h";10 11 my $max_process = 20;12 my $cur_process =0;13 14 my @pid_array;15 16 print "perl fork watcher-worker:\n";17 18 #main start here19 CreateWorker($max_process); 20 21 #child start here22 do_workers();23 24 sub CreateWorker{25 my $workers=shift(@_);26 print $workers,"\n";27 28 my $sign = 1;29 30 while($sign){31 if($workers >0){32 my $pid = fork();33 if($pid >0){34 #watcher35 $sign = 1;36 --$workers;37 }38 elsif($pid == 0){39 #workers40 $sign = 0;41 print "create worker ",$$," success!\n" ;42 do_workers();43 }44 else45 {46 print "fork error: %s\n";47 return -1;48 }49 }50 else{51 #full workers52 my $nStatus;53 while ((my $collect = waitpid(-1, WNOHANG)) > 0)54 {55 print $collect," child process\n";56 $workers++;57 }58 }59 }60 return 0;61 }62 63 sub do_workers{64 #模拟子进程工作65 my $rand=int(rand(10));66 sleep($rand);67 print "child process sleep ",$rand," seconds.\n";68 exit(1);69 }
执行结果如下: