How do you spawn a child process in Ruby?
You can use the fork
kernel method. Here is an example:
#!/usr/bin/env ruby
puts "This is the master process."
child_pid = fork do
puts "This is the child process"
exit
end
puts "The PID of the child process is #{child_pid}"
The fork
method returns the PID of the process it forks and executes any code in the block passed. Like regular Ruby blocks it keeps the bindings of the parent process.
It is a good idea to make your forked process exit
.
Ruby spawn an object method
Just repeating what I said in the comment in an answer, for closure.
since task_start
is not a shell script string, but rather a block of code that should be executed asynchronously, use Process.fork { ov.task_start taskid }
instead of Process.spawn
.
The Process.fork
call returns a PID which can be used to stop the process, for example:
# in one terminal
ruby -e "puts Process.fork { loop { puts('tick'); sleep 1 } }"
# it then prints a PID like 20626
# then in another terminal:
kill -9 20626
# the "tick" will stop getting printed every second.
Spawning simultaneous child processes in Ruby
Here:
stdouts=[]
numberOfProcesses.times do
stdouts<<PTY.spawn(command_line)[0..-1]
end
That's pretty basic if you just spawn them and get a bunch of STDOUT/STDIN pairs. If you want to be able to work on each process's output as soon as it is done, try this:
threads=[]
numberOfProcesses.times do
threads<<Thread.new(command_line) |cmd|
stdout, stdin, pid = PTY.spawn(cmd)
Process.waitpid(pid)
process_output(stdout.read)
end
end
threads.each {|t| t.join}
That spawns them in parallel, each thread waiting for when it's instance is done. When it's instance is done, it processes output and returns. The main thread sits waiting for all of the others to finish.
PID returned by spawn differs from Process.pid of the child process
Looks like the background job operator (&
) is causing the intermediate process 1886789
. When I remove the background job operator, I get the following output:
Hi parent
93185
Start pid 93185
Bye parent
End pid 93185
Run console command in ruby, get PID of child process and kill it in some seconds
The most appropriate solution looks like this:
parent_pid = Process.spawn("gvim", "file_name_to_open")
# Need to wait in order not to kill process till Gvim is started and visible
sleep(5)
Process.kill(9, parent_pid)
# Try to get all Gvim PIDs: the result will look like list of PIDs in
# descending order, so the first one is the last Gvim opened.
all_gvim_pids = `pidof gvim`
last_gvim_pid = all_gvim_pids.split(' ').map(&:to_i).first
Process.kill(9, last_gvim_pid)
The solution is strange and hacky, but noone has better ideas :(
Related Topics
Nested Object Creation with JSON in Rails
How to Track Down a Memory Leak in My Ruby Code
Aws Elastic Beanstalk - How to Upgrade Existing Environment from Ruby 2.1 to Ruby 2.2
Class Method VS Constant in Ruby/Rails
How to Set the Default String Encoding on Ruby 1.9
Ruby: Extracting Words from String
Difference Between 'Self.Method_Name' and 'Class << Self' in Ruby
What Is the "Equals Greater Than" Operator => in Ruby
Difference Between '%{}', '%Q{}', '%Q{}' in Ruby String Delimiters
Rails Search with Optional Parameters
Using Helpers in Rails 3 to Output HTML
Full Url for an Image-Path in Rails 3
How to Convert PDF Files to Images Using Rmagick and Ruby
Ruby: Proc.New { 'Waffles' } VS. Proc { 'Waffles' }