Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ruby - fork, exec, detach .... do we have a race condition here?

Tags:

ruby

cygwin

Simple example, which doesn't work on my platform (Ruby 2.2, Cygwin):

#!/usr/bin/ruby
backtt = fork { exec('mintty','/usr/bin/zsh','-i') }
Process.detach(backtt)
exit

This tiny program (when started from the shell) is supposed to span a terminal window (mintty) and then get me back to the shell prompt.

However, while it DOES create the mintty window, I don't have a shell prompt afterwards, and I can't type anything in the calling shell.

But when I introduce a small delay before the detach, either using 'sleep', or by printing something on stdout, it works as expected:

#!/usr/bin/ruby
backtt = fork { exec('mintty','/usr/bin/zsh','-i') }
sleep 1
Process.detach(backtt)
exit

Why is this necessary?

BTW, I'm well aware that I could (from the shell) do a

mintty /usr/bin/zsh -i &

directly, or I could use system(...... &) from inside Ruby, but this is not the point here. I'm particularily interested in the fork/exec/detach behaviour in Ruby. Any insights?

like image 491
user1934428 Avatar asked Jul 07 '15 05:07

user1934428


1 Answers

Posting as an answer, because it is too long for a comment

Although I am no specialist in Ruby, and do not know Cygwin at all, this situation sounds very familiar to me, coming from C/C++.

This script is too short, so the parent of the parent completes, while the grandchild tries to start.

What would happen if you put the sleep after detach and before exit?

If my theory is correct, it should work too. Your program exits before any (or enough) thread-switching happens.

I call such problems "interrupted hand shaking". Although this is psychology terminology, it describes what happens.

Sleep "gives up the time slice", leading to thread-switching,

Console output (any file I/O) runs into semaphores, also leading to thread switching.

If my idea is correct, it should also work, if you dont "sleep", just count to 1e9 (depending on the speed of computation) because then preemptive multitasking makes even the thread-switch itself not giving up the CPU.

So it is an error in programming (IMHO: race condition is philosophical in that case), but it will get hard to find "who" is responsible. There are many things involved.

like image 61
halfbit Avatar answered Nov 16 '22 01:11

halfbit