win32-gui-tk-thread-dequeue.pl, Thread::Queue::popnow/push
If you write your Win32::GUI like this (like I discuss here and BrowserUk demonstrates) it should work the same way
#!/usr/bin/perl --
## perltidy -olq -csc -csci=10 -cscl="sub : BEGIN END" -otr -opr -ce
+-nibc -i=4 -pt=0 "-nsak=*"
use strict;
use warnings;
use threads;
use threads::shared;
use Thread::Queue;
Main( @ARGV );
exit( 0 );
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
sub mechtitles {
my( $qin, $qout ) = @_;
threads->detach(); ## can't join me :)
require WWW::Mechanize;
my $ua = WWW::Mechanize->new( autocheck => 0 );
while( 1 ) {
if( defined( my $url = $qin->popnow ) ) {
$ua->get( $url );
my $title = eval { $ua->title };
$title ||= $ua->res->status_line;
$qout->push( "$url =>\n $title\n" );
}
threads->yield();
}
} ## end sub mechtitles
sub tkgui {
my( $qin, $qout ) = @_;
require Tk;
require Tk::ROText;
my $mw = Tk::tkinit();
my $pending = "";
my $l = $mw->Label( -textvariable => \$pending )->pack;
my $t = $mw->ROText()->pack;
my $b = $mw->Button( -text => 'enqueue another 3 example.com', )->
+pack;
$b->configure( -command => [ \&q_pusher, $b, $qin, ], );
$b->focus;
$mw->repeat(
500, ## ms
[ \&pop_to_pending, $t, \$pending, $qin, $qout, ],
);
$mw->MainLoop;
return;
} ## end sub tkgui
sub q_pusher {
my( $b, $qin ) = @_;
$qin->push( 'http://example.com' ) for 1 .. 3;
$b->configure( -state => "disabled" );
return;
}
sub pop_to_pending {
my( $t, $pending, $qin, $qout ) = @_;
if( defined( my $item = $qout->popnow ) ) {
$t->insert( q!end!, join( '', $item ) );
}
$$pending = 'Pending ' . $qin->pending;
return;
}
sub Thread::Queue::push { goto &Thread::Queue::enqueue }
sub Thread::Queue::popnow { goto &Thread::Queue::dequeue_nb }