in reply to Perl Tk and Threads

Tk is not thread safe, but you can use threads with it with precautions.

1. The thread must be created before any Tk widgets are invoked. You violate that rule by creating the thread in a button callback.

2. Do not put any Tk code into the thread, and do not try to access Tk widgets from the thread. Use shared variables to communicate with the main thread, and have a timer or fileevent in the main Tk thread, read from the thread.

Here is a very simple example (limited error checking)

#!/usr/bin/perl use warnings; use strict; use threads; use threads::shared; my $ret:shared = 0; my $die:shared = 0;; my $val = 0; #create thread before any tk code is called my $thr = threads->create( \&worker ); use Tk; my $mw = MainWindow->new(); $mw->protocol('WM_DELETE_WINDOW' => sub { &clean_exit }); my $label = $mw->Label( -width => 50, -textvariable => \$val )->pack(); my $button; $button = $mw->Button( -text => 'Stop thread', -command => sub{ $button->configure(-state=>'disabled'); $die = 1; $thr->join; }, )->pack(); my $timer = $mw->repeat(10,sub{ $val = $ret; }); MainLoop; sub clean_exit{ $timer->cancel; my @running_threads = threads->list; if (scalar(@running_threads) < 1){print "\nFinished\n";exit} else{ $die = 1; $thr->join; exit; } } # no Tk code in thread sub worker { for(1..10){ print "$_\n"; $ret = $_; if($die){return} sleep 1; } $ret = 'thread done, ready to join'; print "$ret\n"; }
If you want to launch threads from GUI callbacks, you may have better luck with Perl/Gtk2; but even with it's thread-safety mechanism, it is still more foolproof to make your thread before any Gtk2 widgets are invoked.

I'm not really a human, but I play one on earth Remember How Lucky You Are

Replies are listed 'Best First'.
A reply falls below the community's threshold of quality. You may see it by logging in.