Thread.new do
loop do
rios, = select [o,e], nil, nil
rios.map do |rio|
next if rio.eof?
Thread.critical = true # blocks w/o this
rio.nonblock{ text = rio.read }
Thread.critical = false # blocks w/o this
l.configure :text=>text
end
end
end
Tk.mainloop
is this an o.k. technique to prevent a non-blocking read not to hand a
multi-threaded ap? i’m think of adding an asychronous processing option to my
session library using this feature… actually i suppose it’d always be o.k.
for this to be there…
-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 :: Solar-Terrestrial Physics Data | NCEI
TRY :: for l in ruby perl;do $l -e “print "\x3a\x2d\x29\x0a"”;done
===============================================================================
Thread.new do
loop do
rios, = select [o,e], nil, nil
rios.map do |rio|
Why do you use map here? Apparently you don’t access the result of
mapping so each would be more appropriate.
next if rio.eof?
Thread.critical = true # blocks w/o this
rio.nonblock{ text = rio.read }
Thread.critical = false # blocks w/o this
l.configure :text=>text
end
end
end
Tk.mainloop
is this an o.k. technique to prevent a non-blocking read not to hand a
multi-threaded ap?
I’m not really sure I understand correctly what you’re after. Could you
elaborate that?
Generally speaking there’s one piece of advice:
When using Thread.critical= it is always best to do reset the flag in an
ensure clause to make sure that the reset occurs under all conditions:
Thread.critical = true
begin
do stuff
ensure
Thread.critical = false
end
i’m think of adding an asychronous processing option to my
session library using this feature… actually i suppose it’d always be
o.k.
for this to be there…
Thread.new do
loop do
rios, = select [o,e], nil, nil
rios.map do |rio|
Why do you use map here? Apparently you don’t access the result of
mapping so each would be more appropriate.
right you are - in the actual code i do - this is a distilled example…
next if rio.eof?
Thread.critical = true # blocks w/o this
rio.nonblock{ text = rio.read }
Thread.critical = false # blocks w/o this
l.configure :text=>text
end
end
end
Tk.mainloop
is this an o.k. technique to prevent a non-blocking read not to hand a
multi-threaded ap?
I’m not really sure I understand correctly what you’re after. Could you
elaborate that?
a) why is the critical section needed to prevent one thread blocking the
entire process?
b) is this approach (critical section) the correct way of dealing with this
issue?
more fundmenetally WHY does using ‘nonblock/read’ block a thread when other io
ops, ‘gets’ for example do not? WHAT is the relationship between ioctl ops
and Thread.critical?
Generally speaking there’s one piece of advice:
When using Thread.critical= it is always best to do reset the flag in an
ensure clause to make sure that the reset occurs under all conditions:
Thread.critical = true
begin
do stuff
ensure
Thread.critical = false
end
yes of course - i’ve always wondered why that one doesn’t take a block…
Thread.new do
loop do
rios, = select [o,e], nil, nil
rios.map do |rio|
Why do you use map here? Apparently you don’t access the result of
mapping so each would be more appropriate.
right you are - in the actual code i do - this is a distilled example…
Ah!
next if rio.eof?
Thread.critical = true # blocks w/o this
rio.nonblock{ text = rio.read }
Thread.critical = false # blocks w/o this
l.configure :text=>text
end
end
end
Tk.mainloop
is this an o.k. technique to prevent a non-blocking read not to hand
a
multi-threaded ap?
I’m not really sure I understand correctly what you’re after. Could
you
elaborate that?
a) why is the critical section needed to prevent one thread blocking
the
entire process?
That’s an interesting question. One would rather expect
“Thread.critical=true” to block the whole process. I guess, that there
are no thread context changes without these methods and assigning to
Thread.critical has the side effect of doing a context switch if possible.
I’d try to use “Thread.pass” after “l.configure…” instead of
“Thread.critical” to give other threads a chance to run and see what
happens.
b) is this approach (critical section) the correct way of dealing with
this
issue?
If the blocking is indeed caused by the loop spinning endlessly,
Thread.pass is a far better alternative. You could as well use sleep to
achieve the same.
more fundmenetally WHY does using ‘nonblock/read’ block a thread when
other io
ops, ‘gets’ for example do not? WHAT is the relationship between ioctl
ops
and Thread.critical?
That I don’t know, maybe Matz or Nobu can comment on that.
Generally speaking there’s one piece of advice:
When using Thread.critical= it is always best to do reset the flag in
an
ensure clause to make sure that the reset occurs under all conditions:
Thread.critical = true
begin
do stuff
ensure
Thread.critical = false
end
yes of course - i’ve always wondered why that one doesn’t take a
block…
I guess because normally it’s not intended for use in the open range.
Normally one would use higher level constructs such as Mutex, Queue etc.
That’s an interesting question. One would rather expect
“Thread.critical=true” to block the whole process. I guess, that there are
no thread context changes without these methods and assigning to
Thread.critical has the side effect of doing a context switch if possible.
I’d try to use “Thread.pass” after “l.configure…” instead of
“Thread.critical” to give other threads a chance to run and see what
happens.
b) is this approach (critical section) the correct way of dealing with
this
issue?
If the blocking is indeed caused by the loop spinning endlessly, Thread.pass
is a far better alternative. You could as well use sleep to achieve the
same.
it’s the actual call to nonblock that blocks the process, try this using the
two different approaches between the print statements:
Thread.new do
loop do
rios, = select [o, e], nil, nil
rios.map do |rio|
next if rio.eof?
p ‘start…’
rio.nonblock{ text = rio.read } # blocks #text = rio.gets # does not block
p ‘finish’
l.configure :text=>text
end
end
end
Tk.mainloop
i also tried a couple of ways on inserting Thread.pass - outside of nonblock’s
block, inside of it, etc. - nothing works except protecting the call to read
by critical/exclusive which does really make sense since the point of nonblock
is not to?