Tuesday, December 12, 2006

Pages 141-2: Running multiple processes - Independent children, Blocks and subprocesses


Listen to this article.

Value: Average

Level: Hard

Summary:
You can give a subprocess its job, come back to your business, and the wait for its end.
In the first example code the call to Kernel.fork returns a process ID in the parent, and nil in the child, so the child process will perform the Kernel.exec call and run sort. Process.wait call waits for the sort to complete (and returns its process ID).
If you don't want to wait you can be notified when a child exits. Just set up a signal handler using Kernel.trap.
In the second example code we set up a trap on SIGCLD, which is the signal sent on death of child process.
If you pass IO.popen a command, such as date, and then a block, the block will be passed an IO object as a parameter. The IO object will be closed automatically when the code block exits, just as it is with File.open.
If you associate a block with Kernel.fork, the code in the block will be run in a Ruby subprocess, and the parent will continue after the block.

Memo: $? is a global variable that contains information on the termination of a subprocess.

Example:
exec("sort testfile > output.txt") if fork.nil?
# The sort is now running in a child process
# carry on processing in the main program
# ... dum di dum ...
# then wait for the sort to finish
Process.wait

trap("CLD") do
pid = Process.wait
puts "Child pid #{pid}: terminated"
end
exec("sort testfile > output.txt") if fork.nil?
# do other stuff...

IO.popen("date") {|f| puts "Date is #{f.gets}" }

fork do
puts "In child, pid = #$$" # what is $$ ?
exit 99
end
pid = Process.wait
puts "Child terminated, pid = #{pid}, status = #{$?.exitstatus}"

Reported errata (at 10/17/06 14:17:18 PDT): 0

Errata I found: 0

My suggestions to the author: 2
* (see doubts below)

Doubts: 2
* How does fork.nil? exactly work ?
* What is $$ ?

0 Comments:

Post a Comment

<< Home