BUG: threads and ruby/tk

Hi there,

Here is the code:

···

#!/usr/bin/ruby

require “tk”
$count=TkVariable.new "start"
l=TkLabel.new {
pack
}
l.textvariable $count

TkButton.new {
text "Test"
command proc {puts “a”}
pack
}
t=Thread.new {
loop {
$count.value=“blah”

10000.times {1}

}

}
Tk.mainloop

This program executed with ruby 1.6.7 (2002-03-19) [i386-linux] on a P75
segfaults randomly when I push the “Test” button. If I uncomment the
delay loop, then not segfaults, only if I (with great timing) push the
button exactly when the $count.value=() method is executed.

Sample output:

fery@domesticus:~$ ./test2.rb
a
a
a
/usr/lib/ruby/1.6/tk.rb:880: [BUG] Segmentation fault
ruby 1.6.7 (2002-03-19) [i386-linux]
Aborted

The same program on ruby 1.6.6 (2001-12-26) [i586-mswin32] on winXP
(Athlon 1G) develops different symptom: if I try to move the Tk window,
the program freezes. The bug is present also if the t thread contains
only an empty loop. The segfault on buttonpress is not detected.

Bye:
Circum

Here is the code:
[snippits]

$count=TkVariable.new “start”
t=Thread.new {
loop {
$count.value=“blah”
}
}
Tk.mainloop

Classic problem.

You set Tk stuff from a second thread, where the mainloop expects to be
the only one doing so. In other words, race conditions. The result:
totally weird behaviour. I would be curious whether other toolkits suffer
from this, too.

The solution is called TkAfter and I should probably write a chapter about
it in my tutorial.

Example I got from Hidetoshi Nagai:

···

require ‘tk’
tlist = [500, 2000]
TkAfter.new(proc{t = tlist.shift; tlist.push(t); t}, -1,
proc{p 1}, proc{p 2}).start
Tk.mainloop

This script will print “1” after waiting 0.5s at first,
and “2” after waiting 2.0s from the end of printing “1”.
After that, it will repeat same process.

Hope this helps,
Kero.

±-- Kero ------------------------------ kero@chello.nl —+

Don’t split your mentality without thinking twice |
Proud like a God – Guano Apes |
±-- M38c ---------- http://httpd.chello.nl/k.vangelder —+

Hello,

Here is the code:
[snippits]

$count=TkVariable.new “start”
t=Thread.new {
loop {
$count.value=“blah”
}
}
Tk.mainloop

Classic problem.

You set Tk stuff from a second thread, where the mainloop expects to be
the only one doing so. In other words, race conditions. The result:
totally weird behaviour. I would be curious whether other toolkits suffer
from this, too.

The solution is called TkAfter and I should probably write a chapter about
it in my tutorial.

Yeah, the example helped a lot. Especially, my program was a
graph-drawing program, where one loop lasted cca. 2.3 seconds with my
thread-solution. Now it takes 0.08 seconds. :-)))) BIG difference…

Thank you:
Circum