Beefy Boxes and Bandwidth Generously Provided by pair Networks
Think about Loose Coupling
 
PerlMonks  

Roll your own Event-loop

by zentara (Archbishop)
on Mar 21, 2006 at 23:27 UTC ( [id://538341]=CUFP: print w/replies, xml ) Need Help??

Ever get stuck in a console based app, where you need a nested while(1) loop to sit in a holding pattern, while you watch variables, or filehandles? It is handy to have a Event loop in these cases. You can start the loop anytime in your script, and bust out of it later, to continue linear program flow.

The Gtk2 GUI system, is built upon a non-gui base called Glib. For unix-like systems, you first need the c-libs installed (Cairo, Glib, Pango, Atk, Gtk2) available at gtk+ Most linux distributions come with these preinstalled, so you can run mozilla, gimp, etc. Once you have the c libs installed, you get the Perl interfaces to them, at Perl/Gtk2 . There are win32 ports at Gtk2-win32

You can use the Glib::MainLoop in console based programs to watch filehandles, run multiple timers( which can do just about anything ), and probably other things which your creativity can come up with. This is the console based version of the MainLoop, which Tk and Gtk2 programmers are familiar with.

After you launch the program, start another to write to the test.log file, and see the io_watch monitor the filehandle. Like

echo 'yadda yadda' >>test.log

#!/usr/bin/perl use warnings; use strict; use Glib; # Glib provides a few ready-made event sources, # Glib::Timeout, Glib::Idle, and Glib::IO->add_watch # read perldoc Glib::MainLoop my $main_loop = Glib::MainLoop->new; my $count = 1; my $timer = Glib::Timeout->add (1000, \&timer_callback, undef, 1 ); #my $timer = Glib::Timeout->add ($interval, $callback, $data=undef, $ +pri- # ority=G_PRIORITY_DEFAULT) # * $interval (integer) number of milliseconds # * $callback (subroutine) # * $data (scalar) # * $priority (integer) # Run $callback every $interval milliseconds until $callback return +s # false. Returns a source id which may be used with # "Glib::Source->remove". Note that a mainloop must be active for # the timeout to execute. sub timer_callback{ $count++; print "$count\n"; return 1; } my $count1 = 1; my $timer1 = Glib::Timeout->add (100, \&timer1_callback, undef, 1 ); sub timer1_callback{ $count1++; print "\t$count1\n"; return 1; } ### filehandle watch open (FH, "+> test.log") or warn "$!\n"; Glib::IO->add_watch (fileno 'FH', ['in'], \&watch_callback, 'FH', 1 ); # integer = Glib::IO->add_watch ($fd, $condition, $callback, $data=und +ef, $priority=G_PRIORITY_DEFAULT) # * $fd (Glib::IO) file number, e.g. fileno($filehandle) # * $condition (Glib::IOCondition) # * $callback (subroutine) # * $data (scalar) # * $priority (integer) $main_loop->run; #################################################################### sub watch_callback { my ($fd, $condition, $fh) = @_; my @lines = <FH>; print @lines; #always return TRUE to continue the callback return 1; }

Replies are listed 'Best First'.
Re: Roll your own Event-loop
by elmex (Friar) on Apr 15, 2008 at 09:56 UTC

    The Tutorial is very nice. But these days there is AnyEvent on CPAN, which abstracts away any specific event loop. It has backends for Glib, Tk (*sigh*), EV, Event, Coro and also it's own pure-Perl implementation (via select). It's equally useful and as good for quick scripts as for large applications.

    It doesn't matter much for the application, but if you are going to write a module that requires waiting for I/O events, AnyEvent is a very good choice. It doesn't need or enforce a framework like POE but can still be used by those.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: CUFP [id://538341]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others imbibing at the Monastery: (6)
As of 2024-04-19 16:45 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found