As pointed out, Ruby's threads aren't kernel threads. The scheduling is done by Ruby itself which means that individual opcodes aren't preempted. As backticks are a single opcode, regardless of what you put in them, the opcode won't return, and therefore can't be preempted until the command has finished.
However, you can avoid that by using IO.popen and reading the commands output 1 line at a time
t1 = Thread.new { output = []; cmd = IO.popen( "dir /s u:\\", 'r' ); while cmd.gets output.push $_ end Thread.current["output"] = output } ... t1.join got = t1["output"] got.each{|line| puts line}
That said, you don't appear to be using the output from the backticks, so you probably shouldn't be using them anyway.
As with Perl's threads, you gotta learn to use'em right :)
The nice thing about Ruby's threads is that they are very light. When playing with them a while ago I modified the simple example from the Ruby book and started 100,000 of them concurrently and it only required 130 MB.
With Perl's threads you'll be limited to 64 120* concurrent under Win32 (a Perl implementation limit not Win32), and they will consume 40 MB for even the simplest of subs.
*Update:The limit used to be the same as the pseudo-processes limit, which is still 64, but the threads limit (as of 5.8.6) has been raised to 120. This discovered via the use of the following snippet:
use threads; @t = map{ threads->create( sub{ print threads->self->tid; sleep 60; print threads->self->tid; } ) or die "threads->create failed $^E" } 1 .. 1000;
Which produces
C:\test>maxthreads.pl 1 2 3 ... 116 118 117 threads->create failed Not enough storage is available to process this + command at C:\test\maxthreads.pl li A thread exited while 120 threads were running.
Update2: Having given up trying to unwind the multitude of defines equivalences that surround PERL_GET_CONTEXT
(and the associated mess that is the whole aTHX pTHX pTHX_ thing), I gave up and took a different tack, that of asking the operating system what TLS indexes are being used. The upshot is that whatever the storage is that is being run out of, it isn't TLS indexes.PERL_SET_CONTEXT(aTHX) PERL_SET_CONTEXT((aTHX = PL_sharedsv_space)) PERL_SET_CONTEXT((aTHX = caller_perl)) PERL_SET_CONTEXT(interp) PERL_SET_CONTEXT(aTHX) PERL_SET_CONTEXT(thread->interp) PERL_SET_CONTEXT(aTHX) PERL_SET_THX(t) PERL_SET_CONTEXT(t) PERL_SET_CONTEXT PERL_SET_INTERP(i) Perl_set_context((void*)t) cthread_set_data(cthread_self(), t) (PL_current_context = t) PERL_SET_THX(t) PERL_SET_CONTEXT(t) PERL_SET_CONTEXT(proto_perl);
From what I can work out, the storage in question is Thread Local Storage, which is a limited resource of 1088 32-bit words per process. The current limit of 120 threads suggests that perl is using 9 or 10 32-bit words of TLS per thread. I think I once suggested that this data could be allocated from the heap, and just a single pointer to it stored in TLS. One extra level of indirection would raise the limit to the OS maximum. There may be considerations relating to the architecture of Perl that make this suggestion impractical.
In reply to Re: Score: Perl 1, Ruby 0
by BrowserUk
in thread Score: Perl 1, Ruby 0
by hackdaddy
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |