Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Working with Unix processes

Working with Unix processes

A short talk I gave about Working with Unix processes based on the ebook by Jesse Storimer at the "Amsterdam.rb Reboot" on June 19th of 2012 at the 80beans office.

Dax Huiberts

June 19, 2012
Tweet

More Decks by Dax Huiberts

Other Decks in Programming

Transcript

  1. puts "parent process pid is #{Process.pid}" if fork puts "entered

    the if block from #{Process.pid}" else puts "entered the else block from #{Process.pid}" end
  2. parent process pid is 5054 entered the if block from

    5054 entered the else block from 5078
  3. puts "parent process pid is #{Process.pid}" fork do puts "I'm

    the child: #{Process.pid}" end puts "I'm still the parent: #{Process.pid}"
  4. On certain platforms, when a Resque worker reserves a job

    it immediately forks a child process. The child processes the job then exits. When the child has exited successfully, the worker reserves another job and repeats the process.
  5. Why? Because Resque assumes chaos. Resque assumes your background workers

    will lock up, run too long, or have unwanted memory growth.
  6. Thanks to Resque's parent / child architecture, jobs that use

    too much memory release that memory upon completion. No unwanted growth.
  7. if @child = fork srand # Reseeding procline "Forked #{@child}

    at #{Time.now.to_i}" Process.wait(@child) else procline "Processing #{job.queue} since #{Time.now.to_i}" perform(job, &block) exit! unless @cant_fork end
  8. if @child = fork srand # Reseeding procline "Forked #{@child}

    at #{Time.now.to_i}" Process.wait(@child) else procline "Processing #{job.queue} since #{Time.now.to_i}" perform(job, &block) exit! unless @cant_fork end
  9. if @child = fork srand # Reseeding procline "Forked #{@child}

    at #{Time.now.to_i}" Process.wait(@child) else procline "Processing #{job.queue} since #{Time.now.to_i}" perform(job, &block) exit! unless @cant_fork end
  10. if @child = fork srand # Reseeding procline "Forked #{@child}

    at #{Time.now.to_i}" Process.wait(@child) else procline "Processing #{job.queue} since #{Time.now.to_i}" perform(job, &block) exit! unless @cant_fork end
  11. $ ps -e -o pid,command | grep [r]esque 92099 resque:

    Forked 92102 at 1253142769 92102 resque: Processing file_serve since 1253142769
  12. require 'socket' # Open a socket. socket = TCPServer.open('0.0.0.0', 8080)

    # For keeping track of child process (worker) pids. wpids = [] # Create 5 workers. 5.times do |i| wpids << fork do loop do connection = socket.accept connection.puts 'Hello Readers!' connection.close end end end Process.waitall
  13. require 'socket' # Open a socket. socket = TCPServer.open('0.0.0.0', 8080)

    # For keeping track of child process (worker) pids. wpids = [] # Create 5 workers. 5.times do |i| wpids << fork do loop do connection = socket.accept connection.puts 'Hello Readers!' connection.close end end end Process.waitall
  14. # For keeping track of child process (worker) pids. wpids

    = [] # Create 5 workers. 5.times do |i| wpids << fork do trap(:INT) { exit } loop do # ... end end end # Forward any relevant signals to the child processes. trap(:INT) do wpids.each { |wpid| Process.kill(:INT, wpid) } exit end Process.waitall
  15. # For keeping track of child process (worker) pids. wpids

    = [] # Create 5 workers. 5.times do |i| wpids << fork do trap(:INT) { exit } loop do # ... end end end # Forward any relevant signals to the child processes. trap(:INT) do wpids.each { |wpid| Process.kill(:INT, wpid) } exit end Process.waitall