ktats****@users*****
ktats****@users*****
2011年 9月 23日 (金) 23:25:22 JST
Index: docs/modules/Parallel-ForkManager-0.7.9/lib/Parallel/ForkManager.pod diff -u /dev/null docs/modules/Parallel-ForkManager-0.7.9/lib/Parallel/ForkManager.pod:1.1 --- /dev/null Fri Sep 23 23:25:22 2011 +++ docs/modules/Parallel-ForkManager-0.7.9/lib/Parallel/ForkManager.pod Fri Sep 23 23:25:22 2011 @@ -0,0 +1,763 @@ +=encoding utf8 + +=head1 åå + +=begin original + +Parallel::ForkManager - A simple parallel processing fork manager + +=end original + +Parallel::ForkManager - ç°¡åãªä¸¦åå¦çã«ããforkããã¼ã¸ã£ã¼ + +=head1 æ¦è¦ + + use Parallel::ForkManager; + + $pm = new Parallel::ForkManager($MAX_PROCESSES); + + foreach $data (@all_data) { + # Forks and returns the pid for the child: + my $pid = $pm->start and next; + + ... do some work with $data in the child process ... + ... åããã»ã¹ã«ãã$dataã«é¢ããããã¤ãã®å¦çãè¡ã ... + + $pm->finish; # Terminates the child process + } + +=head1 説æ + +=begin original + +This module is intended for use in operations that can be done in parallel +where the number of processes to be forked off should be limited. Typical +use is a downloader which will be retrieving hundreds/thousands of files. + +=end original + +ãã®ã¢ã¸ã¥ã¼ã«ã¯ç¨¼åä¸ã«ããã¦ä¸¦åå¦çããããã¨ãæå³ãã¦ãã. +ãã®é,ããã»ã¹ã®åå²æ°ã¯å¶éãããã¹ããã®ã§ãã. +å ¸åçãªä½¿ããæ¹ã¨ãã¦ã¯ãã¡ã¤ã«ã®æ°ç¾/æ°åãåå¾ãããã¦ã³ãã¼ãã¼ã¨ãã¦ã§ãã. + +=begin original + +The code for a downloader would look something like this: + +=end original + +ãã¦ã³ãã¼ãã¼ã®ã³ã¼ãã¨ãã¦ã¯ãã®ããã«ãªãã§ããã: + + + use LWP::Simple; + use Parallel::ForkManager; + + ... + + @links=( + ["http://www.foo.bar/rulez.data","rulez_data.txt"], + ["http://new.host/more_data.doc","more_data.doc"], + ... + ); + + ... + + # Max 30 processes for parallel download + # æ大30ããã»ã¹ã§ä¸¦åçã«ãã¦ã³ãã¼ããè¡ãã¾ã + my $pm = new Parallel::ForkManager(30); + + foreach my $linkarray (@links) { + $pm->start and next; # do the fork + # forkããã¾ã + + my ($link,$fn) = @$linkarray; + warn "Cannot get $fn from $link" + if getstore($link,$fn) != RC_OK; + + $pm->finish; # do the exit in the child process + # åããã»ã¹ãexitãã¾ã + } + $pm->wait_all_children; + +=begin original + +First you need to instantiate the ForkManager with the "new" constructor. +You must specify the maximum number of processes to be created. If you +specify 0, then NO fork will be done; this is good for debugging purposes. + +=end original + +ã¾ãåãã«ForkManagerã®"new"ã³ã³ã¹ãã©ã¯ã¿ãå ·ä½åããå¿ è¦ãããã¾ã. +ã³ã³ã¹ãã©ã¯ã¿ãä½æããéã«,ããã»ã¹æ°ã®æ大å¤ãæå®ããªããã°ãªãã¾ãã. +ããããã»ã¹æ°ã0ã¨æå®ããå ´åã¯forkã¯ãããªãã§ããã;ããã¯ãããã°ãè¡ãçºã®ããæ¹æ³ã§ã. + +=begin original + +Next, use $pm->start to do the fork. $pm returns 0 for the child process, +and child pid for the parent process (see also L<perlfunc(1p)/fork()>). +The "and next" skips the internal loop in the parent process. NOTE: +$pm->start dies if the fork fails. + +=end original + +次ã«,forkããçºã«$pm->startã使ãã¾ã. $pmã¯åããã»ã¹ã®çºã«0ã«ãè¿ã, +親ããã»ã¹ã®çºã«åpidãè¿ãã¾ã (ã¾ãã¯, L<perlfunc(1p)/fork()>ãè¦ã¦ä¸ãã). +"and next"ã¯è¦ªããã»ã¹ã«ãããå é¨ã®ç¹°ãè¿ããã¹ããããã¾ã. 注æ: +$pm->startã¯forkã失æããã°æ»ã«ã¾ã. + +=begin original + +$pm->finish terminates the child process (assuming a fork was done in the +"start"). + +=end original + +$pm->finishã¯åããã»ã¹ãçµäºããã¾ã ("start"ã§forkãéå§ããã¨ä»®å®ããå ´å). + +=begin original + +NOTE: You cannot use $pm->start if you are already in the child process. +If you want to manage another set of subprocesses in the child process, +you must instantiate another Parallel::ForkManager object! + +=end original + +注æ:ããªãããã§ã«åããã»ã¹ã«å± ãã®ãªãã°,$pm->startã使ããã¨ã¯ã§ãã¾ãã. +åããã»ã¹ããã1ã»ãã,ãµãããã»ã¹ã¨ãã¦ç®¡çãããã®ãªãã°, +å¥ã®Parallel::ForkManagerãªãã¸ã§ã¯ããå ·ä½åããå¿ è¦ãããã¾ã. + +=head1 ã¡ã½ãã + +=begin original + +The comment letter indicates where the method should be run. P for parent, +C for child. + +=end original + +å¾ãã®ã³ã¡ã³ãã¯ã©ãã§ã¡ã½ããã使ããã示ãã¦ãã¾ã.P ã¯è¦ªããã»ã¹ã§, +Cãåããã»ã¹ã§ã. + +=over 5 + +=item new $processes [, $tempdir] # P + +=begin original + +Instantiate a new Parallel::ForkManager object. You must specify the maximum +number of children to fork off. If you specify 0 (zero), then no children +will be forked. This is intended for debugging purposes. + +=end original + +æ°ããParallel::ForkManagerãªãã¸ã§ã¯ããå ·ä½åãã¾ã. +åããã»ã¹ãåå²ãããæ大æ°ãæå®ããªããã°ãªãã¾ãã. +0ãæå®ããå ´åã¯åå²ãããåã¯ããã¾ãã. +ããã¯ãããã°ç®çã®ããã«æå³ããã¾ã. + +=begin original + +The optional second parameter, $tempdir, is only used if you want the +children to send back a reference to some data (see RETRIEVING DATASTRUCTURES +below). If not provided, it is set to $L<File::Spec>->tmpdir(). + +=end original + +ãªãã·ã§ã³ã®äºçªç®ã®ãã©ã¡ã¼ã¿$tempdirã¯,åããã»ã¹ããä½ããã®ãã¼ã¿ããªãã¡ã¬ã³ã¹ã¨ã㦠+æ»ãããå ´åã«ã®ã¿ä½¿ãã¾ã(å¾è¿°ã®RETRIEVING DATASTRUCTURES ãåç §). +ä¸ããããªããã°,$L<File::Spec>->tmpdir() ãã»ãããã¾ã. + +=begin original + +The new method will die if the temporary directory does not exist or it is not +a directory, whether you provided this parameter or the +$L<File::Spec>->tmpdir() is used. + +=end original + +new ã¡ã½ããã¯ãã³ãã©ãªãã£ã¬ã¯ããªãåå¨ããªãã,ããããã£ã¬ã¯ããªã§ãªããã°æ»ã«ã¾ã. +ãã©ã¡ã¿ã渡ãã¦ã,$L<File::Spec>->tmpdir()ã使ããã¦ãåãã§ã. + +=item start [ $process_identifier ] # P + +This method does the fork. It returns the pid of the child process for +the parent, and 0 for the child process. If the $processes parameter +for the constructor is 0 then, assuming you're in the child process, +$pm->start simply returns 0. + +=end original + +ãã®ã¡ã½ããã¯forkãå®è¡ãã¾ã. +åããã»ã¹ã®pidã親ããã»ã¹ã«è¿ã,åããã»ã¹ã«ã¯0ãè¿ãã¾ã. +$processesãã©ã¡ã¼ã¿ãã³ã³ã¹ãã©ã¯ã¿ã«0ã¨ãã¦æ¸¡ãããå ´å, +ããªãããã§ã«åããã»ã¹ã«å± ãã¨ä»®å®ãã, +$pm->startã¯åã«0ãè¿ãã¾ã. + +=begin original + +An optional $process_identifier can be provided to this method... It is used by +the "run_on_finish" callback (see CALLBACKS) for identifying the finished +process. + +=end original + +ä»»æã§$process_identifierï¼ããã»ã¹èå¥åï¼ãã¡ã½ããã«æä¾ãããã¨ãã§ãã¾ã... +ããã¯"run_on_finish"ã§çµäºããããã»ã¹ãç¹å®ãååããçºã«ä½¿ããã¾ã. +(CALLBACKSã®é ç®ãè¦ã¦ä¸ãã) + +=item finish [ $exit_code [, $data_structure_reference] ] # C + +=begin original + +Closes the child process by exiting and accepts an optional exit code +(default exit code is 0) which can be retrieved in the parent via callback. +If the second optional parameter is provided, the child attempts to send +it's contents back to the parent. If you use the program in debug mode +($processes == 0), this method just calls the callback. + +=end original + +exit ã§åããã»ã¹ãéã,ãªãã·ã§ã³ã¨ãã¦çµäºã³ã¼ããåãã¾ã(è¦å®ã® çµäºã³ã¼ã㯠0 ã§ã). +çµäºã³ã¼ãã¯,ã³ã¼ã«ããã¯çµç±ã§è¦ªããã»ã¹ãåå¾ã§ãã¾ã. +ï¼çªç®ã®ãã©ã¡ã¼ã¿ã渡ããå ´å,åããã»ã¹ã¯è¦ªããã»ã¹ã«ãã®å 容ãéããã¨ãã¾ã. +ãã®ããã°ã©ã ããããã°ã¢ã¼ãã§ä½¿ç¨ããå ´å ($processes == 0 ã®å ´å), +ãã®ã¡ã½ããã¯åã«ã³ã¼ã«ããã¯ãå¼ã³ã¾ã. + +=begin original + +If the $data_structure_reference is provided, then it is serialized and +passed to the parent process. See RETRIEVING DATASTRUCTURES for more info. + +=end original + +$data_structure_reference ã渡ãããå ´åã¯,ã·ãªã¢ã©ã¤ãºããã¦è¦ªããã»ã¹ã«æ¸¡ããã¾ã. +詳細ã¯RETRIEVING DATASTRUCTURES ãè¦ã¦ãã ãã. + +=item set_max_procs $processes # P + +=begin original + +Allows you to set a new maximum number of children to maintain. + +=end original + +æ°ããåããã»ã¹æ°ã®æ大å¤ãè¨å®ãããã¨ãã§ãã¾ã. + +=item wait_all_children # P + +=begin original + +You can call this method to wait for all the processes which have been +forked. This is a blocking wait. + +=end original + +forkãããå ¨ã¦ã®åããã»ã¹ãå¾ ã¤çºã«ãã®ã¡ã½ãããå¼ã¶ãã¨ãã§ãã¾ã. +ããã¯ããããã³ã°ãã wait ã§ã. + +=back + +=head1 ã³ã¼ã«ãã㯠+ +=begin original + +You can define callbacks in the code, which are called on events like starting +a process or upon finish. Declare these before the first call to start(). + +=end original + +ããã»ã¹ã®éå§æã¾ãã¯çµäºæã®ã¤ãã³ãã§å¼ã°ããã³ã¼ã«ããã¯ãå®ç¾©ãããã¨ãã§ãã¾ã. +ãããã¯æåã®start()ã®å¼ã³åºãããåã«å®ç¾©ãã¦ãã ãã. + +=begin original + +The callbacks can be defined with the following methods: + +=end original + +ã³ã¼ã«ããã¯ã¯ä»¥ä¸ã®ã¡ã½ããã§å®ç¾©ãããã¨ãã§ãã¾ã: + +=over 4 + +=item run_on_finish $code [, $pid ] # P + +=begin original + +You can define a subroutine which is called when a child is terminated. It is +called in the parent process. + +=end original + +åããã»ã¹ãçµäºããéã«å¼ã°ãããµãã«ã¼ãã³ãå®ç¾©ãããã¨ãã§ãã¾ã. +ããã¯è¦ªããã»ã¹ããå¼ã°ãã¾ã. + +=begin original + +The paremeters of the $code are the following: + +=end original + +$codeã®ãã©ã¡ã¼ã¿ã¯ä»¥ä¸ã§ã: + +=begin original + + - pid of the process, which is terminated + - exit code of the program + - identification of the process (if provided in the "start" method) + - exit signal (0-127: signal name) + - core dump (1 if there was core dump at exit) + - datastructure reference or undef (see RETRIEVING DATASTRUCTURES) + +=end original + + - çµäºããããã»ã¹ã®pid + - ããã°ã©ã ã®çµäºã³ã¼ã + - ããã»ã¹ã®èå¥ ("start"ã¡ã½ããã§æä¾ãããå ´å) + - çµäºã·ã°ãã« (0-127: ã·ã°ãã«å) + - ã³ã¢ãã³ã (1 ã¯ã³ã¢ãã³ãã«ããçµäºã§ã) + - ãã¼ã¿æ§é ã®ãªãã¡ã¬ã³ã¹undef (RETRIEVING DATASTRUCTURES åç §) + +=item run_on_start $code # P + +=begin original + +You can define a subroutine which is called when a child is started. It called +after the successful startup of a child in the parent process. + +=end original + +åããã»ã¹ãéå§ããéã«å¼ã°ãããµãã«ã¼ãã³ãå®ç¾©ãããã¨ãã§ãã¾ã. +親ããã»ã¹ã®ä¸ã§åããã»ã¹ãæ£å¸¸ã«éå§ãããå¾ã«å¼ã°ãã¾ã. + +=begin original + +The parameters of the $code are the following: + +=end original + +$codeã®ãã©ã¡ã¼ã¿ã¯ä»¥ä¸ã§ã: + +=begin original + + - pid of the process which has been started + - identification of the process (if provided in the "start" method) + +=end original + + - éå§ãããããã»ã¹ã®pid + - ããã»ã¹ã®èå¥ ("start"ã¡ã½ããã§æä¾ãããå ´å) + +=item run_on_wait $code, [$period] # P + +=begin original + +You can define a subroutine which is called when the child process needs to wait +for the startup. If $period is not defined, then one call is done per +child. If $period is defined, then $code is called periodically and the +module waits for $period seconds betwen the two calls. Note, $period can be +fractional number also. The exact "$period seconds" is not guarranteed, +signals can shorten and the process scheduler can make it longer (on busy +systems). + +=end original + +åããã»ã¹ãéå§æã«å¾ ã¡ãå¿ è¦ã¨ããå ´åã«å¼ã°ãããµãã«ã¼ãã³ãå®ç¾©ãããã¨ãã§ãã¾ã. +$periodãå®ç¾©ããã¦ããªãå ´å,ä¸ã¤ã®åããã»ã¹åä½ã§å¼ã³ã¾ã. +$periodãå®ç¾©ããã¦ããå ´å,$codeã¯å®æçã«å¼ã°ã,ã¢ã¸ã¥ã¼ã«ã¯$periodç§ã®éã« +ï¼åº¦å¼ã°ããã®ãã¢ã¸ã¥ã¼ã«ã¯å¾ ã¡ã¾ã +注æ,$periodã¯æççãªæ°ã§ããããããã¾ãã. +æ£ç¢ºãª"$period seconds"ã§ãããã¨ã¯ä¿éãã¾ãã, +ã·ã°ãã«ã¯ç縮ãããã¨ãã§ã,ããã»ã¹ã¹ã±ã¸ã¥ã¼ã©ã¼ã§ã¯é·ããããã¨ãã§ãã¾ã (å¿ããã·ã¹ãã ã§ã¯). + +=begin original + +The $code called in the "start" and the "wait_all_children" method also. + +=end original + +$codeã¯"start"ã"wait_all_children"ã¡ã½ããã«ããå¼ã¶ãã¨ãã§ãã. + +=begin original + +No parameters are passed to the $code on the call. + +=end original + +ãã©ã¡ã¼ã¿ããªãå ´åã¯å¼ã³åºãã®éã«$codeã¯ãã¹ãããã¨ãã§ãã. + +=back + +=head1 ä¾ + +=head1 RETRIEVING DATASTRUCTURES from child processes + +=begin original + +The ability for the parent to retrieve data structures is new as of version +0.7.6. + +=end original + +親ããã»ã¹ã§ãã¼ã¿æ§é ãåå¾ããæ©è½ã¯0.7.6ã®æ°æ©è½ã§ã. + +=begin original + +Each child process may optionally send 1 data structure back to the parent. +By data structure, we mean a reference to a string, hash or array. The +contents of the data structure are written out to temporary files on disc +using the L<Storable> modules' store() method. The reference is then +retrieved from within the code you send to the run_on_finish callback. + +=end original + +ååããã»ã¹ã¯ãªãã·ã§ã³ã¨ãã¦1ã¤ã®ãã¼ã¿æ§é ã親ããã»ã¹ã«æ»ãã¾ã. +ãã¼ã¿æ§é ã¨ã¯,ããã§ã¯,æåå,ããã·ã¥,é åã®ãªãã¡ã¬ã³ã¹ã®ãã¨ã§ã. +ãã¼ã¿æ§é ã®å 容ã¯ãã£ã¹ã¯ã«ä¸æãã¡ã¤ã«ã«L<Storable>ã¢ã¸ã¥ã¼ã«ã®store()ã¡ã½ããã§æ¸ãåºããã¾ã. +ãªãã¡ã¬ã³ã¹ã¯run_on_finish ã³ã¼ã«ããã¯ã«éã£ãã³ã¼ãå ã§åå¾ããã¾ã. + +=begin original + +The data structure can be any scalar perl data structure which makes sense: +string, numeric value or a reference to an array, hash or object. + +=end original + +ãã¼ã¿æ§é ã¯,次ã®ãããªã©ã®ãããªã¹ã«ã©ã®ãã¼ã¿æ§é ã§ãå¯è½ã§ã: +æåå,æ°å¤,é åãããã·ã¥ããªãã¸ã§ã¯ãã®ãªãã¡ã¬ã³ã¹ + +=begin original + +There are 2 steps involved in retrieving data structures: + +=end original + +ãã¼ã¿æ§é ã®åå¾ã«éãã¦,2ã¤ã®ã¹ããããããã¾ã. + +=begin original + +1) A reference to the data structure the child wishes to send back to the +parent is provided as the second argument to the finish() call. It is up +to the child to decide whether or not to send anything back to the parent. + +=end original + +1) åããã»ã¹ã親ããã»ã¹ã«è¿ããããã¼ã¿æ§é ã®ãªãã¡ã¬ã³ã¹ã¯ +finish()å¼ã³åºãã®äºçªç®ã®å¼æ°ã¨ãã¦ä¸ãããã¾ã. +親ã«ä½ããè¿ããã©ããã¯,åããã»ã¹æ¬¡ç¬¬ã§ã. + +=begin original + +2) The data structure reference is retrieved using the callback provided in +the run_on_finish() method. + +=end original + +2) ãã¼ã¿æ§é ã®ãªãã¡ã¬ã³ã¹ã¯run_on_finish ã¡ã½ããã§ä¸ããããã³ã¼ã«ããã¯ã使ã£ã¦ +åå¾ããã¾ã. + +=begin original + +Keep in mind that data structure retrieval is not the same as returning a +data structure from a method call. That is not what actually occurs. The +data structure referenced in a given child process is serialized and +written out to a file by L<Storable>. The file is subsequently read back +into memory and a new data structure belonging to the parent process is +created. Please consider the performance penality it can imply, so try to +keep the returned structure small. + +=end original + +ãã¼ã¿æ§é ã®åå¾ã¯ã¡ã½ããå¼ã³åºããããã¼ã¿æ§é ãæ»ã£ã¦ããã®ã¨ã¯,åãã§ã¯ãªããã¨ã +è¦ãã¦ããã¦ãã ãã.ããã¯å®éã«èµ·ãã¦ãããã§ã¯ããã¾ãã. +åããã»ã¹ã§ãªãã¡ã¬ã³ã¹ã«ããããã¼ã¿æ§é ã¯ã·ãªã¢ã©ã¤ãºãã,L<Storable>ã§ãã¡ã¤ã«ã« +æ¸ãåºããã¾ã.ãã¡ã¤ã«ã¯é çªã«ã¡ã¢ãªã«èªã¿æ»ãã,親ããã»ã¹ã«å±ããæ°ãããã¼ã¿æ§é ã +ä½ããã¾ã.ããã«ããããã©ã¼ãã³ã¹ã®ä½ä¸ãããèãã¦ä¸ãã.ããã¦,æ»ãæ§é ã¯å°ãã +ãã¦ãã ãã. + +=head1 ä¾ + +=head2 並å get + +=begin original + +This small example can be used to get URLs in parallel. + +=end original + +並åçã«URLãåå¾ããçºã«ä½¿ç¨ãããç°¡åãªä¾ã§ã. + + use Parallel::ForkManager; + use LWP::Simple; + my $pm=new Parallel::ForkManager(10); + for my $link (@ARGV) { + $pm->start and next; + my ($fn)= $link =~ /^.*\/(.*?)$/; + if (!$fn) { + warn "Cannot determine filename from $fn\n"; + } else { + $0.=" ".$fn; + print "Getting $fn from $link\n"; + my $rc=getstore($link,$fn); + print "$link downloaded. response code: $rc\n"; + }; + $pm->finish; + }; + +=head2 ã³ã¼ã«ãã㯠+ +=begin original + +Example of a program using callbacks to get child exit codes: + +=end original + +ã³ã¼ã«ããã¯ã使ã£ã¦,åããã»ã¹ãã®çµäºã³ã¼ããå¾ãå ´åã®ä¾ã§ã: + + use strict; + use Parallel::ForkManager; + + my $max_procs = 5; + my @names = qw( Fred Jim Lily Steve Jessica Bob Dave Christine Rico Sara ); + # hash to resolve PID's back to child specific information + + my $pm = new Parallel::ForkManager($max_procs); + + # Setup a callback for when a child finishes up so we can + # get it's exit code + # åããã»ã¹ãçµäºããéã«çµäºã³ã¼ããåå¾ããçºã®è¨å® + $pm->run_on_finish( + sub { my ($pid, $exit_code, $ident) = @_; + print "** $ident just got out of the pool ". + "with PID $pid and exit code: $exit_code\n"; + } + ); + + $pm->run_on_start( + sub { my ($pid,$ident)=@_; + print "** $ident started, pid: $pid\n"; + } + ); + + $pm->run_on_wait( + sub { + print "** Have to wait for one children ...\n" + }, + 0.5 + ); + + foreach my $child ( 0 .. $#names ) { + my $pid = $pm->start($names[$child]) and next; + + # This code is the child process + # ãã®ã³ã¼ãã¯åããã»ã¹ã§ã + print "This is $names[$child], Child number $child\n"; + sleep ( 2 * $child ); + print "$names[$child], Child $child is about to get out...\n"; + sleep 1; + $pm->finish($child); # pass an exit code to finish + } + + print "Waiting for Children...\n"; + $pm->wait_all_children; + print "Everybody is out of the pool!\n"; + +=head2 ãã¼ã¿æ§é ã®åå¾ + +=begin original + +In this simple example, each child sends back a string reference. + +=end original + +ãã®ä¾ã§ã¯,ååããã»ã¹ã¯æååã®ãªãã¡ã¬ã³ã¹ãéã£ã¦ãã¾ã. + + use Parallel::ForkManager 0.7.6; + use strict; + + my $pm = new Parallel::ForkManager(2, '/server/path/to/temp/dir/'); + + # data structure retrieval and handling + # ãã¼ã¿æ§é ã®åå¾ã¨åæ± + $pm -> run_on_finish ( # called BEFORE the first call to start() + sub { + my ($pid, $exit_code, $ident, $exit_signal, $core_dump, $data_structure_reference) = @_; + + # retrieve data structure from child + # ãã¼ã¿æ§é ãåããã»ã¹ããåå¾ + if (defined($data_structure_reference)) { # children are not forced to send anything + my $string = ${$data_structure_reference}; # child passed a string reference + print "$string\n"; + } else { # problems occuring during storage or retrieval will throw a warning + print qq|No message received from child process $pid!\n|; + } + } + ); + + # prep random statement components + my @foods = ('chocolate', 'ice cream', 'peanut butter', 'pickles', 'pizza', 'bacon', 'pancakes', 'spaghetti', 'cookies'); + my @preferences = ('loves', q|can't stand|, 'always wants more', 'will walk 100 miles for', 'only eats', 'would starve rather than eat'); + + # run the parallel processes + # 並åããã»ã¹ãå®è¡ + my $person = ''; + foreach $person (qw(Fred Wilma Ernie Bert Lucy Ethel Curly Moe Larry)) { + $pm->start() and next; + + # generate a random statement about food preferences + my $statement = $person . ' ' . $preferences[int(rand @preferences)] . ' ' . $foods[int(rand @foods)]; + + # send it back to the parent process + # 親ããã»ã¹ã¸æ»ã + $pm->finish(0, \$statement); # note that it's a scalar REFERENCE, not the scalar itself + } + $pm->wait_all_children; + +=begin original + +A second datastructure retrieval example demonstrates how children decide +whether or not to send anything back, what to send and how the parent should +process whatever is retrieved. + +=end original + +次ã®ãã¼ã¿æ§é ãåå¾ããä¾ã§ã¯,ã©ã®ããã«åããã»ã¹ãä½ããè¿ããã©ããã決ãã¦ãããã¨, +ã©ã®ããã«è¦ªããã»ã¹ãåå¾ãããã®ãå¦çãããããã¢ã³ã¹ãã¬ã¼ã·ã§ã³ãã¦ãã¾ã. + +=for example begin + + use Parallel::ForkManager 0.7.6; + use Data::Dumper; # to display the data structures retrieved. + use strict; + + my $pm = new Parallel::ForkManager(20); # using the system temp dir $L<File::Spec>->tmpdir() + + # data structure retrieval and handling + my %retrieved_responses = (); # for collecting responses + $pm -> run_on_finish ( + sub { + my ($pid, $exit_code, $ident, $exit_signal, $core_dump, $data_structure_reference) = @_; + + # see what the child sent us, if anything + if (defined($data_structure_reference)) { # test rather than assume child sent anything + my $reftype = ref($data_structure_reference); + print qq|ident "$ident" returned a "$reftype" reference.\n\n|; + if (1) { # simple on/off switch to display the contents + print &Dumper($data_structure_reference) . qq|end of "$ident" sent structure\n\n|; + } + + # we can also collect retrieved data structures for processing after all children have exited + $retrieved_responses{$ident} = $data_structure_reference; + } else { + print qq|ident "$ident" did not send anything.\n\n|; + } + } + ); + + # generate a list of instructions + my @instructions = ( # a unique identifier and what the child process should send + {'name' => '%ENV keys as a string', 'send' => 'keys'}, + {'name' => 'Send Nothing'}, # not instructing the child to send anything back to the parent + {'name' => 'Childs %ENV', 'send' => 'all'}, + {'name' => 'Child chooses randomly', 'send' => 'random'}, + {'name' => 'Invalid send instructions', 'send' => 'Na Na Nana Na'}, + {'name' => 'ENV values in an array', 'send' => 'values'}, + ); + + my $instruction = ''; + foreach $instruction (@instructions) { + $pm->start($instruction->{'name'}) and next; # this time we are using an explicit, unique child process identifier + + # last step in child processing + $pm->finish(0) unless $instruction->{'send'}; # no data structure is sent unless this child is told what to send. + + if ($instruction->{'send'} eq 'keys') { + $pm->finish(0, \join(', ', keys %ENV)); + + } elsif ($instruction->{'send'} eq 'values') { + $pm->finish(0, [values %ENV]); # kinda useless without knowing which keys they belong to... + + } elsif ($instruction->{'send'} eq 'all') { + $pm->finish(0, \%ENV); # remember, we are not "returning" anything, just copying the hash to disc + + # demonstrate clearly that the child determines what type of reference to send + } elsif ($instruction->{'send'} eq 'random') { + my $string = q|I'm just a string.|; + my @array = qw(I am an array); + my %hash = (type => 'associative array', synonym => 'hash', cool => 'very :)'); + my $return_choice = ('string', 'array', 'hash')[int(rand 3)]; # randomly choose return data type + $pm->finish(0, \$string) if ($return_choice eq 'string'); + $pm->finish(0, \@array) if ($return_choice eq 'array'); + $pm->finish(0, \%hash) if ($return_choice eq 'hash'); + + # as a responsible child, inform parent that their instruction was invalid + } else { + $pm->finish(0, \qq|Invalid instructions: "$instruction->{'send'}".|); # ordinarily I wouldn't include invalid input in a response... + } + } + $pm->wait_all_children; # blocks until all forked processes have exited + + # post fork processing of returned data structures + for (sort keys %retrieved_responses) { + print qq|Post processing "$_"...\n|; + } + +=for example end + +=head1 ã㰠㨠å¶é + +=begin original + +Do not use Parallel::ForkManager in an environment, where other child +processes can affect the run of the main program, so using this module +is not recommended in an environment where fork() / wait() is already used. + +=end original + +Parallel::ForkManagerã¯ãã®ãããªç°å¢ã§ã¯ä½¿ããã¨ãã§ãã¾ãã, +å¥ã®åããã»ã¹ãã¡ã¤ã³ããã°ã©ã ã«å½±é¿ãä¸ããå ´å, +ãããã£ã¦ãã®ã¢ã¸ã¥ã¼ã«ã使ç¨ããã®ã¯fork() / wait()ãæ¢ã«ä½¿ç¨ãããç°å¢ã§æ¨è¦ããã¾ãã. + +=begin original + +If you want to use more than one copies of the Parallel::ForkManager, then +you have to make sure that all children processes are terminated, before you +use the second object in the main program. + +=end original + +ä¸ã¤ä»¥ä¸ã®Parallel::ForkManagerã使ç¨ãããå ´å,主ããã°ã©ã ã§ç¬¬äºã®ãªãã¸ã§ã¯ãã使ç¨ããåã«, +å ¨ã¦ã®åããã»ã¹ãçµäºããã®ã確å®ã«ããªããã°ãªãã¾ãã, + +=begin original + +You are free to use a new copy of Parallel::ForkManager in the child +processes, although I don't think it makes sense. + +=end original + +ããªãã¯åããã»ã¹ã«èªç±ã«Parallel::ForkManagerã®æ°ããã³ãã¼ã使ç¨ãããã¨ãã§ãã¾ã, +ç§ã¯ããã«æå³ãããã¨ã¯æãã¾ããã. + +=head1 COPYRIGHT + +Copyright (c) 2000-2010 Szab坦, Bal叩zs (dLux) + +All right reserved. This program is free software; you can redistribute it +and/or modify it under the same terms as Perl itself. + +=head1 ä½è + + dLux (Szab坦, Bal叩zs) <dlux****@kapu*****> + +=head1 ã¯ã¬ã¸ãã + + Noah Robin <sitz****@onast*****> (documentation tweaks) + Chuck Hirstius <chirs****@megap*****> (callback exit status, example) + Grant Hopwood <hopwo****@valer*****> (win32 port) + Mark Southern <mark_south****@merck*****> (bugfix) + Ken Clarke <www.perlprogrammer.net> (datastructure retrieval) + +=head1 翻訳è + + atsushi kobayashi(nekok****@users*****) + Atsushi Kato (ktat****@cpan*****) -- 0.75 ãã 0.79 ã®å·®åã翻訳