sub Main { my $qin = Thread::Queue->new(); my $qout = Thread::Queue->new(); my $guithread = threads->create( \&tkgui, $qin, $qout ); ## don't wait for background downloading service / mechtitles threads->create( \&mechtitles, $qin, $qout ); $guithread->join; ## wait for gui to finish return; } ## end sub Main #### my $message = { newserialport => [qw/ COM6 baudrate 11 ... /] } ; $qin->push( $message ); #### sub mechtitles { my( $qin, $qout ) = @_; threads->detach(); ## can't join me :) my %dispatch = ( newserialport => \&newserialport, pollserialport => \&pollserialport, ); my %stash; ## STATE require Time::HiRes; while( 1 ) { #~ if( defined( my $url = $qin->popnow ) ) { if( defined( my $action = $qin->pop ) ) { my( $callbackname, $callbackargs ) = %$action; if( my $callback = $dispatch{$callbackname} ){ $callback->(\%stash, $qout, @$callbackargs ); } } Time::HiRes::usleep( 33 * 1000 ); ## microseconds versus miliseconds? grrdoh } } ## end sub mechtitles sub newserialport { my( $stash, $qout, @args ) = @_; my $serialport = Win32::SerialPort->new( ... @args ... ); ... ### THERE IS A NEW STASH IN TOWN $stash->{serialport} = $serialport; } ## end sub newserialport sub pollserialport { my( $stash, $qout, @args ) = @_; ... my $data = $stash->{serialport}->read(1); ## %stash!!!! ... $qout->push( { frobnicatetextdisplay => [ ... $data ... ] ); }