Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Ruby > Threading Question

Reply
Thread Tools

Threading Question

 
 
Mike Houghton
Guest
Posts: n/a
 
      11-16-2006
Hello,

I'm new (very new!) to Ruby but not to programming. I have a
Thread/class inheritance question.I'm trying to make a simple timer
class that extends Thread and repeats a block <count> times and each
repetition separated by <period> seconds. Here's the code

--------------
class Timer < Thread

def initialize( period, count, &action )

puts "Begin initialize"
super
@period = period
@count = count
@action = action
puts "End initialize"

end # initialize


def start

puts "Begin start"

1.upto(@count) do
sleep(@period)
@action.call

end

puts "End start"


end # start


end #class Timer

threads = []

threads << Timer.new(0.77,3){puts "hi"}

threads.each{ |thr| thr.start}

-------

The output is

Begin initialize
hi
End initialize
Begin start
hi
hi
hi
End start

-------

In my ignorance I expected the supplied block not to be executed in
initialize
and to be executed only in the start method. Please would someone
explain where
I'm going wrong and how to correct it.

Many Thanks

Mike




--
Posted via http://www.ruby-forum.com/.

 
Reply With Quote
 
 
 
 
Vincent Fourmond
Guest
Posts: n/a
 
      11-16-2006

Hello !

Mike Houghton wrote:
> In my ignorance I expected the supplied block not to be executed in
> initialize
> and to be executed only in the start method. Please would someone
> explain where
> I'm going wrong and how to correct it.


First reflex, before posting :

ri Thread.new:

------------------------------------------------------------ Thread::new
Thread.new([arg]*) {|args| block } => thread
------------------------------------------------------------------------
Creates and runs a new thread to execute the instructions given in
block. Any arguments passed to Thread::new are passed into the
block.

x = Thread.new { sleep 0.1; print "x"; print "y"; print "z" }
a = Thread.new { print "a"; print "b"; sleep 0.2; print "c" }
x.join # Let the threads finish before
a.join # main thread exits...

produces:

abxyzc

So you see, initialize does run the thread. You might want to write an
independent class that would create the thread in the start function.

Ruby comes with an extensive documentation, at least for standard
classes. I know ri isn't that fast, but faster than any reply here ...

Welcome to Ruby, and enjoy !

Vince

--
Vincent Fourmond, PhD student
http://vincent.fourmond.neuf.fr/


 
Reply With Quote
 
 
 
 
Sylvain Joyeux
Guest
Posts: n/a
 
      11-16-2006
If a block is supplied to Thread.new, this block becomes the thread main loop.
Calling super without parents is equivalent in your case to
super( period, count, &action )

which is basically doing
Thread.new { puts "hi" }

hence the problem
--
Sylvain

 
Reply With Quote
 
Stefano Crocco
Guest
Posts: n/a
 
      11-16-2006
Vincent Fourmond wrote:
> So you see, initialize does run the thread. You might want to write an
> independent class that would create the thread in the start function.


I'm not a thread expert, but I think that something like this should
work

class Timer
def initialize period, count, &action
@period=period
@count=count
@action=action
end

def start
@count.times do |i|
t=Thread.new do
sleep @period
@action.call
end
t.join
end
end

end

t=Timer.new( 3, 4){puts "hello"}
t.start

--
Posted via http://www.ruby-forum.com/.

 
Reply With Quote
 
Vincent Fourmond
Guest
Posts: n/a
 
      11-16-2006

Hello !

Mike Houghton wrote:
> In my ignorance I expected the supplied block not to be executed in
> initialize
> and to be executed only in the start method. Please would someone
> explain where
> I'm going wrong and how to correct it.


First reflex, before posting :

ri Thread.new:

------------------------------------------------------------ Thread::new
Thread.new([arg]*) {|args| block } => thread
------------------------------------------------------------------------
Creates and runs a new thread to execute the instructions given in
block. Any arguments passed to Thread::new are passed into the
block.

x = Thread.new { sleep 0.1; print "x"; print "y"; print "z" }
a = Thread.new { print "a"; print "b"; sleep 0.2; print "c" }
x.join # Let the threads finish before
a.join # main thread exits...

produces:

abxyzc

So you see, initialize does run the thread. You might want to write an
independent class that would create the thread in the start function.

Ruby comes with an extensive documentation, at least for standard
classes. I know ri isn't that fast, but faster than any reply here ...

Welcome to Ruby, and enjoy !

Vince

--
Vincent Fourmond, PhD student
http://vincent.fourmond.neuf.fr/


 
Reply With Quote
 
Phlip
Guest
Posts: n/a
 
      11-16-2006
Mike Houghton wrote:

> I'm new (very new!) to Ruby but not to programming. I have a
> Thread/class inheritance question.I'm trying to make a simple timer
> class that extends Thread and repeats a block <count> times and each
> repetition separated by <period> seconds. Here's the code


Are you coming from Java? It sets a bad example for threading. Don't use it
just for conveniences

Here's an example how Ruby does thready things without the risk and
complexity of threads in your own code:

require 'timeout'
status = Timeout::timeout(5) {
# Something that should be interrupted if it takes too much time...
}

Look up Timeout, and it might do what you need, or lead to a similar
technique.

--
Phlip
http://www.greencheese.us/ZeekLand <-- NOT a blog!!!


 
Reply With Quote
 
Vincent Fourmond
Guest
Posts: n/a
 
      11-16-2006

Hello !

Mike Houghton wrote:
> In my ignorance I expected the supplied block not to be executed in
> initialize
> and to be executed only in the start method. Please would someone
> explain where
> I'm going wrong and how to correct it.


First reflex, before posting :

ri Thread.new:

------------------------------------------------------------ Thread::new
Thread.new([arg]*) {|args| block } => thread
------------------------------------------------------------------------
Creates and runs a new thread to execute the instructions given in
block. Any arguments passed to Thread::new are passed into the
block.

x = Thread.new { sleep 0.1; print "x"; print "y"; print "z" }
a = Thread.new { print "a"; print "b"; sleep 0.2; print "c" }
x.join # Let the threads finish before
a.join # main thread exits...

produces:

abxyzc

So you see, initialize does run the thread. You might want to write an
independent class that would create the thread in the start function.

Ruby comes with an extensive documentation, at least for standard
classes. I know ri isn't that fast, but faster than any reply here ...

Welcome to Ruby, and enjoy !

Vince

--
Vincent Fourmond, PhD student
http://vincent.fourmond.neuf.fr/


 
Reply With Quote
 
Mike Houghton
Guest
Posts: n/a
 
      11-16-2006
Phlip wrote:
> Mike Houghton wrote:
>
>> I'm new (very new!) to Ruby but not to programming. I have a
>> Thread/class inheritance question.I'm trying to make a simple timer
>> class that extends Thread and repeats a block <count> times and each
>> repetition separated by <period> seconds. Here's the code

>
> Are you coming from Java? It sets a bad example for threading. Don't use
> it
> just for conveniences
>
> Here's an example how Ruby does thready things without the risk and
> complexity of threads in your own code:
>
> require 'timeout'
> status = Timeout::timeout(5) {
> # Something that should be interrupted if it takes too much time...
> }
>
> Look up Timeout, and it might do what you need, or lead to a similar
> technique.

Thanks for the comments.
I looked at Timeout and, though it could be used here, I think its for
something more imperative than running a block every n seconds and
besides the block might
not terminate before the timeout.

--
Posted via http://www.ruby-forum.com/.

 
Reply With Quote
 
Vincent Fourmond
Guest
Posts: n/a
 
      11-16-2006
Vincent Fourmond wrote:

Sorry for sending three messages, my ?!#$ SMTP server refused to
deliver two messages, but actually did deliver them half an hour later.

Vince

--
Vincent Fourmond, PhD student
http://vincent.fourmond.neuf.fr/

 
Reply With Quote
 
Mike Houghton
Guest
Posts: n/a
 
      11-16-2006

I tried Vincent's idea of having an independant class and setting the
thread in a start method. i.e.

class Timer

def initialize( period, count, &action )

@period = period
@count = count
@action = action

end #initialize

def start

Thread.new do
@count.times do
@action.call
#sleep(@period)
end #do
end #do


end #start


end #class Timer

timer = Timer.new( 1,5){puts "x"}
timer.start

This works, but if the sleep(@period) is un-commented it only prints "x"
once. If the sleep line is placed before @action.call then "x" is not
printed at all. I've looked at the documentation for sleep but found no
clues.

Thanks

Mike

--
Posted via http://www.ruby-forum.com/.

 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Re: threading in PyQt vs threading in standard library Steven Woody Python 0 01-09-2009 07:48 AM
threading in PyQt vs threading in standard library Steven Woody Python 0 01-09-2009 07:15 AM
Cooperative threading preemptive threading - a bit confused failure_to@yahoo.co.uk Java 9 12-29-2007 01:10 AM
Threading question Frederick Wilson Firefox 1 12-22-2004 12:23 AM
disconnected DataSet multi-threading question Alina ASP .Net 0 07-16-2003 04:23 PM



Advertisments
 



1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57