I tried to write a script that makes use of external binaries. Each
external binary is called from a different thread, but, under 1.8.6,
this doesn’t seem to work. Everything is executing in a sequential-like
manner.
The guys from StackOverflow said this was because of Ruby’s thread
implementation ( and when I tried the same code under JRuby, it worked
).
Is there some way to make my script work under 1.8.6, or is upgrading to
1.9 the only solution?
I tried to write a script that makes use of external binaries. Each
external binary is called from a different thread, but, under 1.8.6,
this doesn’t seem to work. Everything is executing in a sequential-like
manner.
The guys from StackOverflow said this was because of Ruby’s thread
implementation ( and when I tried the same code under JRuby, it worked
).
Is there some way to make my script work under 1.8.6, or is upgrading to
1.9 the only solution?
What do you mean by external binary? Something you invoke with #system
or the like?
I tried to write a script that makes use of external binaries. Each
external binary is called from a different thread, but, under 1.8.6,
this doesn’t seem to work. Everything is executing in a sequential-like
manner.
The guys from StackOverflow said this was because of Ruby’s thread
implementation ( and when I tried the same code under JRuby, it worked
).
Is there some way to make my script work under 1.8.6, or is upgrading to
1.9 the only solution?
I don’t think that is necessary. Can you provide a example of the
phenomenon you describe? Normally, external programs are separate
processes and work independently. It may be though that if you do the
IO handling for external processes not properly that it looks like
they are executed sequentially because they are blocked in IO
operations.
Backticks are blocking calls which return the entirety of their stdout as a
single string on completion of the subprocess.
I cannot open the above link. So I rewrite Joel’s code snippet
using backticks:
t = Thread.new {
puts echo foo; sleep 1; echo bar
}
puts echo baz; sleep 1; echo quux
t.join
Stricly spoken it’s not blocking. The “baz” is written to its pipe
before “bar”. But it is stored until “quux” is echoed and puts is
asked to write it out.
Am Dienstag, 08. Sep 2009, 01:11:23 +0900 schrieb Eleanor McHugh:
asked to write it out.
From Ruby’s perspective the backtick is definitely a blocking IO operation,
just as it is in shell script.
Yes, of course. I just examined the interpreter’s source. The
waitpid function is called without the WNOHANG flag. Before that
the child processes output is read and appended to a string until
the stream is closed what usually happens when the program
terminates.
What I meant was just that the child process is really running and
writing “foo” and “baz” to the pipes 1 second before the output
can by noticed in the parent.
This doesn’t behave different. My Ruby -v outputs this :
What exactly do you mean? What do you expect? If you refer to seeing
the output of both ping commands sequentially: with the code you
presented you always will get your output sequentially simply because
you wait until all threads finish and then you’ll iterate them and print
the output of one thread at a time. Your ping commands will run in
parallel.
Am Dienstag, 08. Sep 2009, 02:05:03 +0900 schrieb Bertram S.:
What I meant was just that the child process is really running and
writing “foo” and “baz” to the pipes 1 second before the output
can by noticed in the parent.
In other words: the child processes don’t block each other.
Is that ok?
The first 4 threads or so are created almost instantly, and after that,
everything runs as if only one thing is executed at a time. I get the
same behaviour no matter how many times I try to run it.
Am Dienstag, 08. Sep 2009, 02:05:03 +0900 schrieb Bertram S.:
What I meant was just that the child process is really running and
writing “foo” and “baz” to the pipes 1 second before the output
can by noticed in the parent.
In other words: the child processes don’t block each other.
Is that ok?
Rather let’s say that child processes won’t block each other due to
the underlying implementation of backtick. It is however still
possible to introduce blocking behaviour by using operations in those
children which would cause blocking, such as accessing a semaphore or
other blocking system resource.