Thread::Queue . while (defined (my $ item = $ queue-> dequeue ())) {
# perform any actions.
}

#! / usr / bin / perl
use strict;
use Tkx; # tulkit
use threads; # work with threads
use Thread :: Queue; # implements the queue
# create queues
my $ queue_tk = Thread :: Queue-> new (); # we get tasks from Tk
my $ queue_job = Thread :: Queue-> new (); # send to employees
my $ queue_box = Thread :: Queue-> new (); # results
# boss
sub thread_boss {
my $ self = threads-> self ();
my $ tid = $ self-> tid ();
while (defined (my $ item = $ queue_tk-> dequeue ())) {
print STDERR "Boss ($ tid) has received the task from Tk: $ item \ n";
# send the task for processing to the employee
$ queue_job-> enqueue ($ item);
}
$ queue_job-> enqueue (undef);
}
# worker (s)
sub thread_worker {
my $ self = threads-> self ();
my $ tid = $ self-> tid ();
while (defined (my $ job = $ queue_job-> dequeue ())) {
print STDERR "Worker ($ tid) has received task from Boss: $ job \ n";
# doing some work ...
print STDERR "Worker ($ tid) has finished the task \ n";
# we throw everything in one box;)
$ queue_box-> enqueue ("processed: $ job");
}
$ queue_box-> enqueue (undef);
}
# create threads
my $ boss = threads-> new (\ & thread_boss);
my $ worker = threads-> new (\ & thread_worker);
# Create UI
my $ main_window = Tkx :: widget-> new ('.');
my $ frame = $ main_window-> new_ttk__frame (-padding => q / 10 10 10 10 /);
$ frame-> g_grid ();
my $ label = $ frame-> new_ttk__label (-text => 'waiting');
$ label-> g_grid (-row => 0, -column => 0, -columnspan => 2);
# input field
my $ entry_data = 'enter data here';
my $ entry = $ frame-> new_ttk__entry (-textvariable => \ $ entry_data);
my $ button = $ frame-> new_ttk__button (
-text => 'Send to Boss',
-command => sub {
$ queue_tk-> enqueue ($ entry_data);
},
);
$ entry-> g_grid (-row => 1, -column => 0);
$ button-> g_grid (-row => 1, -column => 1);
# handler for WM_DELETE_WINDOW
sub on_destroy {
my $ mw = shift;
# send queues undef that will terminate streams
$ queue_tk-> enqueue (undef);
$ queue_box-> enqueue ('finish');
# Destroy
# or Tkx :: destroy ('.')
$ mw-> g_destroy ();
}
$ main_window-> g_wm_protocol ('WM_DELETE_WINDOW', [\ & on_destroy, $ main_window]);
# process the result
sub monitor {
my $ status_lbl = shift;
my $ result = $ queue_box-> dequeue_nb;
if ($ result ne 'finish') {
if (defined $ result) {
$ label-> configure (-text => "job completed:" .scalar (localtime));
}
Tkx :: after (1000, [\ & monitor, $ label]);
}
}
# run monitoring
Tkx :: after (100, [\ & monitor, $ label]);
# detach streams
# otherwise at the end of the program, we will have warnings
# Perl exited with active threads:
# 2 running and unjoined
# 0 finished and unjoined
# 0 running and detached
$ boss-> detach ();
$ worker-> detach ();
Tkx :: MainLoop ();
Source: https://habr.com/ru/post/65592/
All Articles