in reply to Perl Tk and Threads
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)
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.#!/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"; }
|
---|
Replies are listed 'Best First'. | |
---|---|
A reply falls below the community's threshold of quality. You may see it by logging in. |