… | |
… | |
15 | It can be used to create new worker processes or new independent |
15 | It can be used to create new worker processes or new independent |
16 | subprocesses for short- and long-running jobs, process pools (e.g. for use |
16 | subprocesses for short- and long-running jobs, process pools (e.g. for use |
17 | in pre-forked servers) but also to spawn new external processes (such as |
17 | in pre-forked servers) but also to spawn new external processes (such as |
18 | CGI scripts from a webserver), which can be faster (and more well behaved) |
18 | CGI scripts from a webserver), which can be faster (and more well behaved) |
19 | than using fork+exec in big processes. |
19 | than using fork+exec in big processes. |
|
|
20 | |
|
|
21 | Special care has been taken to make this module useful from other modules, |
|
|
22 | while still supporting specialised environments such as L<App::Staticperl> |
|
|
23 | or L<PAR::Packer>. |
20 | |
24 | |
21 | =head1 PROBLEM STATEMENT |
25 | =head1 PROBLEM STATEMENT |
22 | |
26 | |
23 | There are two ways to implement parallel processing on UNIX like operating |
27 | There are two ways to implement parallel processing on UNIX like operating |
24 | systems - fork and process, and fork+exec and process. They have different |
28 | systems - fork and process, and fork+exec and process. They have different |
… | |
… | |
164 | |
168 | |
165 | =back |
169 | =back |
166 | |
170 | |
167 | =cut |
171 | =cut |
168 | |
172 | |
|
|
173 | # the early fork template process |
|
|
174 | our $EARLY; |
|
|
175 | |
169 | # the empty template process |
176 | # the empty template process |
170 | our $TEMPLATE; |
177 | our $TEMPLATE; |
171 | |
178 | |
172 | sub _cmd { |
179 | sub _cmd { |
173 | my $self = shift; |
180 | my $self = shift; |
174 | |
181 | |
175 | # ideally, we would want to use "a (w/a)*" as format string, but perl versions |
182 | # ideally, we would want to use "a (w/a)*" as format string, but perl versions |
176 | # form at least 5.8.9 to 5.16.3 are all buggy and can't unpack it. |
183 | # from at least 5.8.9 to 5.16.3 are all buggy and can't unpack it. |
177 | push @{ $self->[2] }, pack "N/a", pack "(w/a)*", @_; |
184 | push @{ $self->[2] }, pack "N/a", pack "(w/a)*", @_; |
178 | |
185 | |
179 | $self->[3] ||= AE::io $self->[1], 1, sub { |
186 | $self->[3] ||= AE::io $self->[1], 1, sub { |
180 | if (ref $self->[2][0]) { |
187 | if (ref $self->[2][0]) { |
181 | AnyEvent::Fork::Util::fd_send fileno $self->[1], fileno ${ $self->[2][0] } |
188 | AnyEvent::Fork::Util::fd_send fileno $self->[1], fileno ${ $self->[2][0] } |
182 | and shift @{ $self->[2] }; |
189 | and shift @{ $self->[2] }; |
|
|
190 | |
183 | } else { |
191 | } else { |
184 | my $len = syswrite $self->[1], $self->[2][0] |
192 | my $len = syswrite $self->[1], $self->[2][0] |
185 | or do { undef $self->[3]; die "AnyEvent::Fork: command write failure: $!" }; |
193 | or do { undef $self->[3]; die "AnyEvent::Fork: command write failure: $!" }; |
|
|
194 | |
186 | substr $self->[2][0], 0, $len, ""; |
195 | substr $self->[2][0], 0, $len, ""; |
187 | shift @{ $self->[2] } unless length $self->[2][0]; |
196 | shift @{ $self->[2] } unless length $self->[2][0]; |
188 | } |
197 | } |
189 | |
198 | |
190 | unless (@{ $self->[2] }) { |
199 | unless (@{ $self->[2] }) { |
… | |
… | |
278 | |
287 | |
279 | =cut |
288 | =cut |
280 | |
289 | |
281 | sub new_exec { |
290 | sub new_exec { |
282 | my ($self) = @_; |
291 | my ($self) = @_; |
|
|
292 | |
|
|
293 | return $EARLY->fork |
|
|
294 | if $EARLY; |
283 | |
295 | |
284 | # first find path of perl |
296 | # first find path of perl |
285 | my $perl = $; |
297 | my $perl = $; |
286 | |
298 | |
287 | # first we try $^X, but the path must be absolute (always on win32), and end in sth. |
299 | # first we try $^X, but the path must be absolute (always on win32), and end in sth. |