in reply to Re^2: Can I capture string typING in STDIN without press enter?
in thread Can I capture string typING in STDIN without press enter?

Hi, see Glib MainLoop for the MainLoop documentation. Documentation is sparse, but essentially, it waits until the Glib eventloop is idle, before running the sub, so as not to interfere with it. It is seen used more when you try to use Glib or Gtk2 code from a thread. If you get into GUI's, you will often read about the thread safety of the GUI toolkit. Gtk2's thread safety is accomplished principally by only using Glib::Idle->add to access the main gui code from within the thread. Here are a couple of examples.
#!/usr/bin/perl use warnings; use strict; use Glib; use Glib qw/TRUE FALSE/; use threads; use threads::shared; my $count = 0; my $thread; my $die:shared = 0; my $main_loop = Glib::MainLoop->new; #test timer my $timer = Glib::Timeout->add (1000, \&timer_callback, undef, 1 ); #timer to start thread after 4 seconds my $timer1 = Glib::Timeout->add (4000, \&timer1_callback, undef, 1 ); #timer to stop thread after 8 seconds my $timer2 = Glib::Timeout->add (8000, \&timer2_callback, undef, 1 ); $main_loop->run; sub timer_callback{ $count++; print "$count\n"; return 1; } sub timer1_callback{ $thread = threads->new(\&work); return 0; #run once only } sub timer2_callback{ $die = 1; $thread->join; return 0; #run once only } sub work{ $|++; while(1){ foreach my $num (1..1000){ if($die){return} Glib::Idle->add( sub{ print "\t\t$num\n"; return FALSE; }); select(undef,undef,undef, .1); } } } __END__
and with a GUI
#!/usr/bin/perl use warnings; use strict; use threads; use threads::shared; use Glib qw/TRUE FALSE/; use Gtk2 qw/-init -threads-init/; Glib::Object->set_threadsafe (TRUE); #setup shared hash my %shash; share(%shash); #will work for first level keys $shash{'go'} = 0; $shash{'work'} = ''; $shash{'die'} = 0; my $window = Gtk2::Window->new('toplevel'); $window ->signal_connect( 'destroy' => \&delete_event ); $window->set_border_width(10); $window->set_size_request(300,300); my $vbox = Gtk2::VBox->new( FALSE, 6 ); $window->add($vbox); $vbox->set_border_width(2); my $hbox= Gtk2::HBox->new( FALSE, 6 ); my $hbox1 = Gtk2::HBox->new( FALSE, 6 ); $vbox->pack_end($hbox,FALSE,FALSE,0); $vbox->pack_end (Gtk2::HSeparator->new, FALSE, FALSE, 0); $vbox->pack_end($hbox1,FALSE,FALSE,0); $hbox->set_border_width(2); $vbox->pack_end (Gtk2::HSeparator->new, FALSE, FALSE, 0); my $ebutton = Gtk2::Button->new_from_stock('gtk-quit'); $hbox->pack_end( $ebutton, FALSE, FALSE, 0 ); $ebutton->signal_connect( clicked => \&delete_event ); my $pbar = Gtk2::ProgressBar->new(); $pbar->set_pulse_step(.1); $hbox->pack_start($pbar,1,1,0); my $count = 0; my $label_w_markup = Gtk2::Label->new(); $label_w_markup->set_markup("<span foreground=\"yellow1\" size=\"40000\">$count</span>"); $vbox->pack_end($label_w_markup,FALSE,FALSE,4); ###################################################### my $tbutton = Gtk2::Button->new_with_label('Run Thread'); $hbox1->pack_start($tbutton , 1, 1, 0 ); my $lconnect = $tbutton->signal_connect( clicked => sub{ launch() }); my $sconnect; $window->show_all(); $pbar->hide; #needs to be called after show_all #create 1 sleeping thread passing it the label and pbar to control my $thread = threads->new(\&work, $label_w_markup, $pbar); Gtk2->main; ###################################### sub delete_event { $shash{'go'} = 0; $shash{'die'} = 1; $thread->join; Gtk2->main_quit; return FALSE; } ####################################### sub launch{ $pbar->show; $tbutton->set_label('Stop Thread'); $tbutton->signal_handler_block($lconnect); $sconnect = $tbutton->signal_connect( clicked => sub{ stop() }); $shash{'go'} = 1; } ################################################## sub stop{ print "stopped\n"; $shash{'go'} = 0; $pbar->hide; $tbutton->set_label('Run Thread'); $tbutton->signal_handler_block ($sconnect); $tbutton->signal_handler_unblock ($lconnect); } ######################################################### sub work{ my ($label,$pbar) = @_; $|++; while(1){ if($shash{'die'} == 1){ goto END }; if ( $shash{'go'} == 1 ){ foreach my $num (1..1000){ Glib::Idle->add( sub{ if($shash{'die'} == 1){ return }; $label->set_markup("<span foreground=\"yellow1\" size=\"40000\">$num</span>"); $pbar->pulse; return FALSE; }); select(undef,undef,undef, .1); if($shash{'go'} == 0){last} if($shash{'die'} == 1){ goto END }; } $shash{'go'} = 0; #turn off self before returning }else { select(undef,undef,undef,.1) } #sleep time } END: } ###########################################################

I'm not really a human, but I play one on earth.
Old Perl Programmer Haiku ................... flash japh

Replies are listed 'Best First'.
Re^4: Can I capture string typING in STDIN without press enter?
by exilepanda (Friar) on Jun 01, 2012 at 16:24 UTC
    Thanks a lot for all the suggestions and examples. I am going start with your simpler example above first ( looks more familiar style and easier for me ) but see if I will spot some thread safe is needed for the real run... this is a really nice alternative resort! Thanks again, Cheers! =)