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