in reply to Re^3: Thread problems
in thread Thread problems
Hi,
I like the following solution of my problem, although it contains some gotos. But the states in the thread make clear what the expected behaviour should be. It has handshakes and now the code is working exactly as I want.
#!/usr/bin/perl use warnings; use strict; use threads; use threads::shared; use enum qw(:THREAD_CMD_ NONE WAIT WORK DIE); use enum qw(:THREAD_STATE_ WAIT WORK); my %thread_data:shared; $thread_data{'state'} = THREAD_STATE_WAIT; $thread_data{'cmd'} = THREAD_CMD_NONE; $thread_data{'nb'} = 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 $button_stop = $mw->Button(-text => 'Stop thread', -command => sub { $thread_data{'cmd'} = THREAD_CMD_WAI +T; while( $thread_data{'state'} != THRE +AD_STATE_WAIT ) { select(undef, undef, undef, 0.1) +; } })->pack(); my $button_start = $mw->Button(-text => '(Re)Start thread', -command => sub { $thread_data{'cmd'} = THREAD_CMD_WO +RK; while( $thread_data{'state'} != THR +EAD_STATE_WORK ) { select(undef, undef, undef, 0.1 +); } })->pack(); my $entry = $mw->Entry(-textvariable => \$thread_data{'nb'}, -width => + 10)->pack(); MainLoop; sub clean_exit { my @running_threads = threads->list; if (scalar(@running_threads) > 1) { print "ERROR: Too many threads are active. There should be onl +y one thread!\n"; } elsif (scalar(@running_threads) == 1) { $thread_data{'cmd'} = THREAD_CMD_DIE; $thr->join; exit; } else { print "ERROR: There should be at least one thread started!\n"; } } # no Tk code in thread sub worker { my $i = 0; THREAD_STATE_WAIT: $thread_data{'state'} = THREAD_STATE_WAIT; while(1) { if( $thread_data{'cmd'} == THREAD_CMD_WORK ) { $thread_data{'cmd'} = THREAD_CMD_NONE; goto THREAD_STATE_WORK; } elsif( $thread_data{'cmd'} == THREAD_CMD_DIE ) { $thread_data{'cmd'} = THREAD_CMD_NONE; return; } elsif( $thread_data{'cmd'} == THREAD_CMD_WAIT ) { $thread_data{'cmd'} = THREAD_CMD_NONE; goto THREAD_STATE_WAIT; } else { # wait select(undef,undef,undef,0.1); } } THREAD_STATE_WORK: $thread_data{'state'} = THREAD_STATE_WORK; print "\n"; $i = $thread_data{'nb'}; while(1) { if( $thread_data{'cmd'} == THREAD_CMD_WORK ) { $thread_data{'cmd'} = THREAD_CMD_NONE; goto THREAD_STATE_WORK; } elsif( $thread_data{'cmd'} == THREAD_CMD_DIE ) { $thread_data{'cmd'} = THREAD_CMD_NONE; return; } elsif( $thread_data{'cmd'} == THREAD_CMD_WAIT ) { $thread_data{'cmd'} = THREAD_CMD_NONE; goto THREAD_STATE_WAIT; } else { # work print $i . " "; select(undef,undef,undef,0.5); $i++; } } }
Greetings
Dirk
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re^5: Thread problems
by zentara (Cardinal) on Dec 11, 2009 at 16:10 UTC | |
by Dirk80 (Pilgrim) on Dec 13, 2009 at 18:55 UTC |