Method: Parallel::ForkManager#finish
- Defined in:
- lib/parallel/forkmanager.rb
#finish(exit_code = 0, data_structure = nil) ⇒ Object
finish(exit_code, [data_structure]) – exit_code is optional
finish() 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 you’re running the program in debug mode (max_proc == 0), this method just calls the callback.
If data_structure is provided, then data structure is serialized and passed to the parent process. See Retrieving Data Structures in the next section for more info. For example:
%w{Fred Wilma Ernie Bert Lucy Ethel Curly Moe Larry}.each {
|person|
# pm.start(...) here
# ... etc ...
# Pass along data structure to finish().
pm.finish(0, {'person' => person})
}
Retrieving Data Structures
The ability for the parent to retrieve data structures from child processes was adapted to Parallel::ForkManager 1.5.0 (and newer) from Perl Parallel::ForkManager. This functionality was originally introduced in Perl Parallel::ForkManager 0.7.6.
Each child process may optionally send 1 data structure back to the parent. By data structure, we mean a a string, hash, or array. The contents of the data structure are written out to temporary files on disk using the Marshal dump() method. This data structure is then retrieved from within the code you send to the run_on_finish callback.
NOTE NOTE NOTE: Only serialization with Marshal and yaml are supported at this time. Future versions of Parallel::ForkManager may support expanded functionality!
There are 2 steps involved in retrieving data structures:
-
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.
-
The data structure is retrieved using the callback provided in the run_on_finish() method.
Data structure retrieval is not the same as returning a data structure from a method call! The data structure referenced by a given child process is serialized and written out to a file in the type specified earlier in serialize_as. If serialize_as was not specified earlier, then no serialization will be done.
The file is subseqently read back into memory and a new data structure that belongs to the parent process is created. Therefore it is recommended that you keep the returned structure small in size to mitigate any possible performance penalties.
249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 |
# File 'lib/parallel/forkmanager.rb', line 249 def finish(exit_code = 0, data_structure = nil) if @has_block fail "Do not use finish(...) when using blocks. Use an explicit exit in your block instead!\n" end if in_child exit_code ||= 0 unless data_structure.nil? @data_structure = data_structure the_tempfile = "#{@tempdir}Parallel-ForkManager-#{@parent_pid}-#{$PID}.txt" begin fail "Unable to serialize data!" unless _serialize_data(the_tempfile) rescue => e puts "Unable to store #{the_tempfile}: #{e.}" exit 1 end end Kernel.exit!(exit_code) end if @max_procs == 0 on_finish($PID, exit_code, @processes[$PID], 0, 0) @processes.delete($PID) end 0 end |