Ryan Tomayko touched off quite a fire storm with this post about using Unix process control commands.
We should be doing more of this. A lot more of this. I'm talking about fork(2), execve(2), pipe(2), socketpair(2), select(2), kill(2), sigaction(2), and so on and so forth. These are our friends. They want so badly just to help us.
I have a bit of code (a delayed_job
clone for DataMapper that I think would fit right in with this, but I'm not clear on how to take advantage of the listed commands. Any Ideas on how to improve this code?
def start
say "*** Starting job worker #{@name}"
t = Thread.new do
loop do
delay = Update.work_off(self)
break if $exit
sleep delay
break if $exit
end
clear_locks
end
trap('TERM') { terminate_with t }
trap('INT') { terminate_with t }
trap('USR1') do
say "Wakeup Signal Caught"
t.run
end
end
Ahh yes... the dangers of "We should do more of this" without explaining what each of those do and in what circumstances you'd use them. For something like
delayed_job
you may even be usingfork
without knowing that you're usingfork
. That said, it really doesn't matter. Ryan was talking about usingfork
for preforking servers.delayed_job
would usefork
for turning a process into a daemon. Same system call, different purposes. Runningdelayed_job
in the foreground (withoutfork
) vs in the background (withfork
) will result in a negligible performance difference.However, if you write a server that accepts concurrent connections, now Ryan's advice is right on the money.
fork
: creates a copy of the original processexecve
: stops executing the current file and begins executing a new file in the same process (very useful in rake tasks)pipe
: creates a pipe (two file descriptors, one for read, one for write)socketpair
: like a pipe, but for socketsselect
: let's you wait for one or more of multiple file descriptors to be ready with a timeoutkill
: used to send a signal to a processsigaction
: lets you change what happens when a process receives a signal