Hello redss,
Forking and joining may cause the app to crash on some platforms. A way around this is to spawn a worker or pool of workers in the background and send messages via a queue. Below please find two demonstrations, one using threads, the other MCE::Hobo. A shared scalar is constructed for updating the message string. A Tk timer is configured to run at 1/10th interval (fraction of a second).
These examples are based on zentura++'s many examples where I've been validating the upcoming MCE 1.828 and MCE::Shared 1.825 releases alongside Tk, Gtk2, Gtk3, Wx, and what not, including Curses::UI.
First, a threads demonstration.
##
# see also a demonstration by zentara, particularly -textvariable
# http://www.perlmonks.org/?node_id=1087787
#
# my $msg : shared = "Start";
# $btn1 = $mw->Button(-textvariable => \$msg, ...);
# later : $msg = "Step Two"; $btn1->update;
#
# thank you, zentara++
##
use strict;
use warnings;
use threads;
use threads::shared;
use Thread::Queue;
use Tk;
my $que = Thread::Queue->new();
my $msg : shared = "Start";
# detach the thread so not to get thread warnings
# about running threads when exiting the app
(my $thr = threads->create('bg_task'))->detach();
my $mw = MainWindow->new();
$mw->protocol( WM_DELETE_WINDOW => \&quit );
$mw->geometry("+150+100");
$mw->Label( -text => "Tk + threads Demo", -height => 2, -width => 22 )
+->pack;
my $btn1 = $mw->Button( -text => $msg, -command => \&fun, -width => 10
+ );
$btn1->pack();
my $btn2 = $mw->Button( -text => "Quit", -command => \&quit, -width =>
+ 10 );
$btn2->pack();
my $timer = $mw->repeat( 100, sub {
$btn1->configure( -text => $msg );
});
MainLoop();
sub fun {
$que->enqueue("some event");
return;
}
sub quit {
$timer->cancel;
# for threads, is helpful to signal the app to
# terminate so not to segfault on some platforms
kill('TERM', -$$);
exit;
}
sub bg_task {
while ( my $event = $que->dequeue ) {
$msg = "Step One";
sleep 1;
$msg = "Step Two";
sleep 1;
$msg = "Step Three";
}
}
Likewise, a MCE::Hobo demonstration. This does a fork.
##
# see also a demonstration by zentara, particularly -textvariable
# http://www.perlmonks.org/?node_id=1087787
#
# tie my $msg, 'MCE::Shared', "Start"
# $btn1 = $mw->Button(-textvariable => \$msg, ...);
# later : $msg = "Step Two"; $btn1->update;
#
# thank you, zentara++
##
use strict;
use warnings;
use Tk;
use MCE::Hobo;
use MCE::Shared;
my $que = MCE::Shared->queue();
my $msg = MCE::Shared->scalar("Start");
my $hobo = MCE::Hobo->create('bg_task');
my $mw = MainWindow->new();
$mw->protocol( WM_DELETE_WINDOW => \&quit );
$mw->geometry("+150+100");
$mw->Label( -text => "Tk + MCE::Hobo Demo", -height => 2, -width => 22
+ )->pack;
my $btn1 = $mw->Button( -text => $msg->get, -command => \&fun, -width
+=> 10 );
$btn1->pack();
my $btn2 = $mw->Button( -text => "Quit", -command => \&quit, -width =>
+ 10 );
$btn2->pack();
my $timer = $mw->repeat( 100, sub {
$btn1->configure( -text => $msg->get );
});
MainLoop();
sub fun {
$que->enqueue("some event");
return;
}
sub quit {
$timer->cancel;
$hobo->exit->join;
exit;
}
sub bg_task {
while ( my $event = $que->dequeue ) {
$msg->set("Step One");
sleep 1;
$msg->set("Step Two");
sleep 1;
$msg->set("Step Three");
}
}
Thank you Discipulus for introducing zentara recently. Zentara, am pleased to meet you. I've used a couple examples of yours for validating signal handling improvements in MCE 1.828 and MCE::Shared 1.825. I will post what and how after release day, possibly here. But that thread frightens me for some reason. Imho, folks may use any parallel module of their liking or do things by hand if that feels more natural.
Well redss, am not sure if this will work for you. It may be helpful to do a search at the monastery for more Tk demonstrations. I wonder what other folks do myself. For more MCE::Hobo demonstrations, see also this thread by karlgoethebier.
Regards, Mario
This thread is helpful for updating a Tk label. This is where I've learn to update a Tk widget with ->configure.
Found an old post by zentara: Re: Perl Tk and Threads.