in reply to Gtk2 app on Windows, driving a background process
Hello kikuchiyo,
The thread Non-blocking Reads from Pipe Filehandle from 10 years ago is a good read. Thank you for posting the link. Queues typically have non-blocking capabilities. Thus, the reason for taking MCE::Hobo and MCE::Shared for a drive.
I've added a $poll variable to have the timer code leave early unless awaiting a reply.
#!/usr/bin/perl ## # Gtk2 app on Windows, driving a background process: # http://www.perlmonks.org/?node_id=1191637 # # Gtk2 and MCE::Hobo demonstration base on: # http://www.perlmonks.org/?node_id=1191649 ## use strict; use warnings; use Gtk2 -init; use IPC::Open2; use MCE::Hobo (); use MCE::Shared (); my $cmd = $^O eq 'MSWin32' ? 'bc.exe' : 'bc'; my $qjob = MCE::Shared->queue(); my $qres = MCE::Shared->queue(); sub background { my $pid = open2( my $reader, my $writer, $cmd ); print STDERR "=== pid hobo : $$\n"; print STDERR "=== pid bc : $pid\n"; while ( defined ( my $text = $qjob->dequeue() ) ) { print $writer $text; $qres->enqueue(scalar <$reader>); } kill 'TERM', $pid; waitpid $pid, 0; } my $hobo = MCE::Hobo->create(\&background); my $w = Gtk2::Window->new(); my $vbox = Gtk2::VBox->new(); my $l = Gtk2::Label->new(); my $i = Gtk2::Entry->new(); my $poll = 0; $w->signal_connect(destroy => \&cleanup); $i->signal_connect(activate => sub { my $text = $i->get_text(); $qjob->enqueue("$text\n"), $poll = 1; print STDERR ">>> $text\n"; $i->set_text(''); }); Glib::Timeout->add(60, \&update_label); # Emulated fork on Windows returns a negative pid. # The hobo worker can send the bc pid if desired. # E.g.: $qres->enqueue($pid); from inside hobo # my $bc_pid = $qres->dequeue; $l->set_text( "init ".$hobo->pid() ); $vbox->add($i); $vbox->add($l); $w->add($vbox); $w->show_all(); Gtk2->main(); sub update_label { return Glib::SOURCE_CONTINUE unless $poll; my $read = $qres->dequeue_nb(); if (length $read) { $poll = 0, chomp $read; chop $read if $^O eq 'MSWin32'; print STDERR "<<< $read\n"; $l->set_text($read); } return Glib::SOURCE_CONTINUE; } sub cleanup { $qjob->end(), $hobo->join(); Gtk2->main_quit(); }
Regards, Mario.
|
|---|