項目地址: https://gitee.com/lookingdreamer/RexDeploy_v1git
隨着應用愈來愈多,單進程的運行已經嚴重的拖慢了速度.因此多進程就應運而生了.爲何不是多線程?由於rex自己的框架都是採用的多進程.且多進程相對多線程來講要穩定得多.項目自己也去嘗試了多線程,但在兼容性上出現了問題.索性就所有按照多進程去設計和開發.數組
平常生活的比喻多線程
假設商店最大容納人數爲5我的,一共有12我的.只能等前面5我的進去出來以後,後面的5我的才能進入,不足5我的的所有進去併發
轉換爲數學問題框架
將12我的編號爲0到12號spa
#!/bin/perl my ($start,$maxchild,$max,%hash_pids) = (0,5,12) ; for(my $g=0; $g < $max ;){ $startIndex = $g ; $endIndex = $g + $maxchild; if($endIndex > $max){ $endIndex = $max; } $start = $start + 1 ; print("\r\n開始第$start次併發控制:($startIndex - $endIndex) \r\n"); for($i=$startIndex;$i<$endIndex;$i++){ select(undef, undef, undef, 0.25); my $child=fork(); if($child){ print("\r\n父進程PID:$$ 子進程PID:$child\r\n"); $hash_pids{$child} = $child; }else{ # 在子進程中執行相關動做 print("開始執行子進程,進程序號:$i \r\n"); sleep(5); print("結束執行子進程,進程序號:$i \r\n"); exit 0; } } #收割並等待子進程完成 while (scalar keys %hash_pids) { my $kid = waitpid(-1, WNOHANG); if ($kid and exists $hash_pids{$kid}) { delete $hash_pids{$kid}; } } print("結束第$start次併發控制:($startIndex - $endIndex) \r\n"); $g = $g + $maxchild; }
好比我傳名字關鍵詞test1,test3,test4,abc,cde….,由於每一個應用的名字是惟一的,我將名字添加到一個索引數組中 如上0-5對應就是索引數組的第1個到第5個,意味着第一次執行前5個名字的服務.net
my @ks = split(/ /, $k);
關鍵點線程
利用系統fork()建立多進程; 利用waitpid無阻塞的模式收割進程waitpid(-1, WNOHANG); 利用hash保存進程idscala
多進程間通信設計
多進程間通信通常分爲消息隊列、共享內存段以及信號量3種方式.一般狀況下共享內存段和信號配合使用.在個人項目主要是經過IPC::Shareable
模塊來實現進程間的數據共享
use IPC::Shareable; ...... my @shared; my $mainProces = $$; #建立信號 my $ipch = tie @shared, 'IPC::Shareable', "foco", { create => 1, exclusive => 'no', mode => 0666, size => 1024*512, # destroy => 'yes', }; ...... my $single = {"mainProcess"=>"$mainProces","data"=>$runres} ; #持鎖 $ipch->shlock; #保存數據到全局內存 push @shared, $single ; #解鎖 $ipch->shunlock;
保存到全局內存中的數組變量@shared,有可能含有其餘主進程建立的子進程.因此在取出當前進程建立的子進程數據,咱們須要作1個區分.由於在保存數據的時候,咱們把當前的主進程ID也保存進去了.只要內存數據的數組元素的主進程PID等於主進程就是該進程建立的子進程數據.以下
...... my @mainShared; my $u = 0 ; my @deleteArray; Rex::Logger::info("當前全局內存存儲變量數量: $allCount"); for (my $var = 0; $var < $allCount; $var++) { my $process = $shared[$var]->{"mainProcess"}; if ( "$process" eq "$mainProces" ) { $u = $u + 1; push @mainShared,$shared[$var] ; push @deleteArray,$var; } }
建立和消亡進程的時候,對系統帶來必定的開銷.同時也會頻繁的切換CPU.因爲對系統進程的併發的數量沒有限制,對系統來講並非很好控制和友好.不知道perl多進程是否能夠引入多進程池.提早初始一部分線程給程序,而後在分發線程給程序,這樣對CPU的資源以及進程的控制也能達到最大效率化.