From: Daniel Lewis Date: 2005-09-29T19:46:27+09:00 Subject: Re: Ruby and Tk question Deadlocks are usually to do with the OS. Maybe Tk can't cope with threads. Have you tried this in other Graphical Toolkits, WxRuby is quite nice and GTK seems quite good. On 29/09/05, Stephen Kellett wrote: > Hello everyone, > > I've been trying to write a trivial multi-threaded application that has > a GUI (implemented using TkRuby) and which updates various counters on > the GUI. Problem is it deadlocks as soon as I try to update the > graphical part, but I am unsure why. I've included the most stripped > down version of the code here - which will not deadlock - it will just > output to stdout. If you comment in the two obvious lines (commented to > indicate which ones) then it does deadlock. > > Am I doing something wrong? > Have I made incorrect assumptions? > How should I do this? > Is it possible to update Tk components from threads other than the main > GUI thread? > > Cheers > > Stephen > > require 'tk' # get widget classes > require 'thread' > > class RTVExample < TkRoot > def initialize(args) > super(args) > > @countA = 0 > @countB = 0 > @lock1 = Mutex.new > > # create our UI > > @menubar = TkMenubar.new(nil, nil) > @menubar.pack('side'=>'top', 'fill'=>'x') > > @menubar.add_menu([['File', 0], > ['Exit', proc{exitFunc}, 0]]) > > @menubar.add_menu([['Thread Test', 0], > ['Test 1', proc{testThread1}, 0]]) > > @counterLabel = TkLabel.new{text 'Counter' ; pack {padx=30 ; pady=0}} > end > > # why does this deadlock? - surely it should just run the two threads alongside the GUI thread. > > def testThread1() > # create two the threads - comment in the #@counter lines to see the deadlock > > tok1 = Thread.new do > 10000.times { > @lock1.synchronize { @countA += 1 } > puts "A:" + @countA.to_s() > > # this next line causes the deadlock - why? > #@counterLabel.configure(text=>"Counter A: %d" % @countA) > } > end > tok2 = Thread.new do > 10000.times { > @lock1.synchronize { @countB += 1 } > puts "B:" + @countB.to_s() > > # this next line causes the deadlock - why? > #@counterLabel.configure(text=>"Counter B: %d" % @countB) > } > end > > tok1.join > tok2.join > end > > def exitFunc() > TkRoot.destroy() > end > end > > # run the GUI app > > gui = RTVExample.new() > Tk.mainloop() > > -- > Stephen Kellett > Object Media Limited http://www.objmedia.demon.co.uk/software.html > Computer Consultancy, Software Development > Windows C++, Java, Assembler, Performance Analysis, Troubleshooting > >