[#1263] Draft of the updated Ruby FAQ — Dave Thomas <Dave@...>

33 messages 2000/02/08

[#1376] Re: Scripting versus programming — Andrew Hunt <andy@...>

Conrad writes:

13 messages 2000/02/15

[#1508] Ruby/GTK and the mainloop — Ian Main <imain@...>

17 messages 2000/02/19
[#1544] Re: Ruby/GTK and the mainloop — Yasushi Shoji <yashi@...> 2000/02/23

Hello Ian,

[#1550] Re: Ruby/GTK and the mainloop — Ian Main <imain@...> 2000/02/23

On Wed, Feb 23, 2000 at 02:56:10AM -0500, Yasushi Shoji wrote:

[#1516] Ruby: PLEASE use comp.lang.misc for all Ruby programming/technical questions/discussions!!!! — "Conrad Schneiker" <schneiker@...>

((FYI: This was sent to the Ruby mail list.))

10 messages 2000/02/19

[#1569] Re: Ruby: constructors, new and initialise — Yukihiro Matsumoto <matz@...>

The following message is a courtesy copy of an article

12 messages 2000/02/25

[ruby-talk:01551] Ruby thread scheduling buglet

From: Ian Main <imain@...>
Date: 2000-02-24 00:49:57 UTC
List: ruby-talk #1551
You're going to like this one :)

The following program:


----

require "thread"                                
                                
N=4                    
                                                             
def sitter(n)                            
  a = 0                                
  while TRUE                                  
    if (a.remainder (5000) == 0)                                    
      printf ("thread %d at %d\n", n, a)         
    end                                              
  a += 1                                                  
  end  
end    

def sleeper    
  while TRUE
    sleep (0.01)
  end          
end

for i in 0..N-1  
  Thread.start{sitter(i)}            
end                                                   

Thread.start{sleeper}      
    
sleep                                    
    

-----

unexpectedly produces:

thread 0 at 0
thread 0 at 5000
thread 0 at 10000
thread 1 at 0
thread 1 at 5000
thread 1 at 10000
thread 0 at 15000
thread 2 at 0
thread 2 at 5000
thread 2 at 10000
thread 1 at 15000
thread 1 at 20000
thread 0 at 20000
thread 0 at 25000
thread 0 at 30000
thread 3 at 0
thread 3 at 5000
thread 3 at 10000
thread 2 at 15000
thread 2 at 20000
thread 1 at 25000
thread 1 at 30000
thread 0 at 35000
thread 0 at 40000
thread 3 at 15000
thread 3 at 20000
thread 3 at 25000
thread 3 at 30000
thread 3 at 35000
thread 3 at 40000
...

(continuing on thread 3 for the rest of the programs life)

I noticed this because the sleep () call is essentially what the gtk
bindings are using, and you can't run more than one extra thread for them
either.

I think the reason is in rb_thread_schedule ():

...

if (num_waiting_on_timer > 0) {
  now = timeofday();
  FOREACH_THREAD_FROM(curr, th) {
    if (th->wait_for & WAIT_TIME) {
      if (th->delay <= now) {
        th->delay = 0.0;
	th->wait_for &= ~WAIT_TIME;
	th->status = THREAD_RUNNABLE;
	num_waiting_on_timer--;
	next = th;
      } else if (th->delay < delay) {
	delay = th->delay;
      }
    }
  }
  END_FOREACH_FROM(curr, th);
}

...
					    
with the constant calling to sleep, it goes through this every call to
rb_thread_schedule ().  The thread that was sleeping, wakes up probably just
about every run through this function, so its set as the current thread.  It
then loops about, goes to sleep again, and somewhere in there the next
thread is run (thread 3 in our example), but then this one wakes up again
before any others have a chance to run, and the scheduling is reset.


I dunno what the perfect ruby-ish solution is so I'll leave that to you folk.


Ian

























































































In This Thread

Prev Next