signaling another thread

A

Ara.T.Howard

what is is the prefered method in which one thread can 'signal' another thread
on some condition? Observable? other?

eg.

other = Thread.new {
do_important_work
}

watch = Thread.new {
loop {
notify(other) if some_test_that_should_interupt_important_work
}
}


one thing i've considered doing is something like

worker = Thread.new{stop; do_work}
watcher = Thread.new{stop; loop{check or worker.stop}}

watcher.start
worker.start

perhaps this model would be best done using another process and signals since
the potential for the watcher to be put to sleep at a critical time is larger
with threads...

thoughts?

-a
--
===============================================================================
| EMAIL :: Ara [dot] T [dot] Howard [at] noaa [dot] gov
| PHONE :: 303.497.6469
| ADDRESS :: E/GC2 325 Broadway, Boulder, CO 80305-3328
| URL :: http://www.ngdc.noaa.gov/stp/
| TRY :: for l in ruby perl;do $l -e "print \"\x3a\x2d\x29\x0a\"";done
===============================================================================
 
J

Joel VanderWerf

Ara.T.Howard said:
what is is the prefered method in which one thread can 'signal' another thread
on some condition? Observable? other?

One way is to use Thread#raise:

$ cat thread-signal.rb
class PayAttention < Exception; end

other = Thread.new do
i=0
begin
loop do
sleep 1
i += 1 # important work
end
rescue PayAttention
puts i
retry if i < 10
end
end

watch = Thread.new do
loop do
sleep 3
other.raise PayAttention
end
end

other.join

$ ruby thread-signal.rb
2
4
6
8
10
$
 
A

Ara.T.Howard

One way is to use Thread#raise:

$ cat thread-signal.rb
class PayAttention < Exception; end

other = Thread.new do
i=0
begin
loop do
sleep 1
i += 1 # important work
end
rescue PayAttention
puts i
retry if i < 10
end
end

watch = Thread.new do
loop do
sleep 3
other.raise PayAttention
end
end

other.join

$ ruby thread-signal.rb
2
4
6
8
10
$

nice - i'll take it. thanks.

-a
--
===============================================================================
| EMAIL :: Ara [dot] T [dot] Howard [at] noaa [dot] gov
| PHONE :: 303.497.6469
| ADDRESS :: E/GC2 325 Broadway, Boulder, CO 80305-3328
| URL :: http://www.ngdc.noaa.gov/stp/
| TRY :: for l in ruby perl;do $l -e "print \"\x3a\x2d\x29\x0a\"";done
===============================================================================
 
E

Edgardo Hames

Robert said:
It depends on the situation: if the thread to notify may be idle, a
ConditionVariable is better.

I'd take the ConditionVariable approach if I could, otherwise I don't
see why you can't use the Observer Paradigm. Maybe, I'm missing the point.

Regards,
Ed


--
Edgardo Hames
Consultor Informático
Vates S.A. Ingeniería de Software

(e-mail address removed)
Tel: +54 +351 +4240133 int. 121
9 de Julio 228 - 6° piso. Córdoba
 
R

Robert Klemme

Edgardo Hames said:
I'd take the ConditionVariable approach if I could, otherwise I don't
see why you can't use the Observer Paradigm. Maybe, I'm missing the
point.

Hm, dunno how exactly you want to treat this with observer. But you need
some kind of thread synchronization anyway, even if you use observer.

Are you familiar with multithreaded applications?

Regards

robert
 
E

Edgardo Hames

Robert said:
Hm, dunno how exactly you want to treat this with observer. But you need
some kind of thread synchronization anyway, even if you use observer.

Are you familiar with multithreaded applications?

Condition variables, semaphores and monitors grant you exclusive access
to shared resources. That means only one thread will access a resource
in a given moment.

The Observer Paradigm, allows an object to be notified when a certain
event happens. Check the following heavily based on the example in "The
Pragmatic Programmer's Guide" :). I added a method m to the WarnLow
Class that loops until it gets notified.

I hope it helps.
Ed

----8<--------8<--------8<--------8<----
require "observer"




class Ticker
include Observable
def run
i = 0
while (i < 130)
changed(i > 70)
notify_observers(Time.now, i)
i = i + 1
end
end
end

class Warner
def initialize(ticker, limit)
@limit = limit
ticker.add_observer(self) # all warners are observers
end
end


class WarnLow < Warner
def m
@i = 0
loop do
@i = @i + 1
end
end
def update(time, price) # callback for observer
if price < @limit
print "#@i #{time.to_s}: Price below #@limit: #{price}\n"
end
end
end




class WarnHigh < Warner
def update(time, price) # callback for observer
if price > @limit
print "+++ #{time.to_s}: Price above #@limit: #{price}\n"
end
end
end




ticker = Ticker.new()
Thread.new {
wl = WarnLow.new(ticker, 80)
wl.m
}
WarnHigh.new(ticker, 120)
ticker.run



--
Edgardo Hames
Consultor Informático
Vates S.A. Ingeniería de Software

(e-mail address removed)
Tel: +54 +351 +4240133 int. 121
9 de Julio 228 - 6° piso. Córdoba
 
R

Robert Klemme

Edgardo Hames said:
Condition variables, semaphores and monitors grant you exclusive access
to shared resources. That means only one thread will access a resource
in a given moment.

The Observer Paradigm, allows an object to be notified when a certain
event happens. Check the following heavily based on the example in "The
Pragmatic Programmer's Guide" :). I added a method m to the WarnLow
Class that loops until it gets notified.

That code is not thread safe. At least @i is accessed unsychronized.
While it *may* work it is unsafe.

Apart from that: all notifications occur in thread main, no thread really
reacts on the status change. Normally you would have used a condition
variable that was accessed from WarnLow#m and #update. Then you would not
have the thread spinning around doing nothing and waisting resources (CPU
cycles that is).

But this seems to be only an example. It depends on the real problem at
hand which approach is best.

Regards

robert
 
E

Edgardo Hames

Robert said:
That code is not thread safe. At least @i is accessed unsychronized.
While it *may* work it is unsafe.

I know it is unsafe. I just wanted to write an example on how a thread
could be working and stop when a certain event was notified, which you
cannot do if you where using a Condition Variable. A Condition Variable
could be used to guarantee exclusive access to @i.

Ed


--
Edgardo Hames
Consultor Informático
Vates S.A. Ingeniería de Software

(e-mail address removed)
Tel: +54 +351 +4240133 int. 121
9 de Julio 228 - 6° piso. Córdoba
 
R

Robert Klemme

Edgardo Hames said:
I know it is unsafe. I just wanted to write an example on how a thread
could be working and stop when a certain event was notified,

Your thread does neither stop nor is it interrupted. WarnLow#m just does an
endless loop and increments @i without taking any notice of #update calls.
It is the same instance but a different thread context. You can view that
easily by including the current thread in your printout like

class WarnHigh < Warner
def update(time, price) # callback for observer
if price > @limit
print "#{Thread.current.inspect}: +++ #{time}: Price above #@limit:
#{price}\n"
end
end
end

You'll notice that it is the same as the main program, which happens to
execute Ticker#run
which you
cannot do if you where using a Condition Variable.

That's right: with a condition variable the thread is suspended and does
nothing.
A Condition Variable
could be used to guarantee exclusive access to @i.

For exclusive access a mutex is sufficient. The condition variable buys you
the added convenience that a thread is suspended while waiting for a
condition change (technically for a signal to occur).

robert
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads

threads and blocking 0
narray on windows? 1
Class::name 0
thread gurus please help... 7
drb with udp 1
pthread 2
idiot's guide to druby using ssh tunnels 4
pthread masters (that's you guy) 1

Members online

No members online now.

Forum statistics

Threads
473,756
Messages
2,569,534
Members
45,007
Latest member
OrderFitnessKetoCapsules

Latest Threads

Top