in reply to Re^2: Non Blocking input on Win32 platforms
in thread Non Blocking input on Win32 platforms

Let's see what you are advocating here.

use Glib; use Term::ReadKey; use threads; #use threads::shared; $|++; ReadMode('cbreak'); # works non-blocking if read stdin is in a thread my $count = 0; my $thr = threads->new(\&read_in)->detach; my $main_loop = Glib::MainLoop->new; my $timer = Glib::Timeout->add (1000, \&timer_callback, undef, 1 ); # can also have filehandle watches #my $watcher; #$watcher = Glib::IO->add_watch( fileno( $pty ), ['in', 'hup'], \&call +back); $main_loop->run; ReadMode('normal'); # restore normal tty settings sub timer_callback{ #do stuff $count++; print "\n$count\n"; return 1; } sub read_in{ while(1){ my $char; if (defined ($char = ReadKey(0)) ) { print "\t\t$char->", ord($char),"\n"; #process key presses here #if($char eq 'q'){exit} if(length $char){exit} # panic button on any key :-) } } }
  1. use threads;
  2. and use Term::ReadKey;
  3. and use Glib;
  4. and my $timer  = Glib::Timeout->add (1000, \&timer_callback, undef, 1 );
  5. and (despite your "...without a cumbersome while(1) loop."), while(1){

And what does all of that get you? Not a lot!

You still have to write your own line editing, command line history, command line aliases etc. etc.

And if you need to do something that'l take a few seconds, your going to have to break it up into iddy biddy chunks, or lace it through with some do_one_event() call or similar.

when the alternative is:

my $Qstdin = new Thread::Queue; async { $Qstdin->enqueue( $_ ) while defined( $_ = <STDIN> ); }->detach; ... my $kbinput = $Qstdin->dequeue;

Fully cross platform; one thread and no faffing around with iddy biddy callbacks; and all the command line handling your local shell provides--that works in exactly whatever way the local shell provides it.

AND to do other things in the main thread

Rubbish! As soon as you enter that MainLoop-run, your main "thread" is dead until something signals stop.

And you might want to revise your "It also works cross-platform,". From the GLib docs:

The GIOChannel data type aims to provide ... support for Windows is only partially complete.
which can't be said for the Win32 modules.

Oh! And what Win32 modules would that be?


Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
"Science is about questioning the status quo. Questioning authority".
In the absence of evidence, opinion is indistinguishable from prejudice.
"Too many [] have been sedated by an oppressive environment of political correctness and risk aversion."

Replies are listed 'Best First'.
Re^4: Non Blocking input on Win32 platforms
by zentara (Archbishop) on Nov 01, 2008 at 16:40 UTC
    First I clearly said in my original response The solution is to spawn a thread to read STDIN, see Readkey with timer using Glib. You may not need the Glib stuff

    So I posted an example I had, which used a lib that you don't like, and clearly said you may not need the Glib stuff, the secret is to put the STDIN watcher in a thread. I figured a poster that asked a question like that could understand the value of reading a single key from STDIN in a non-blocking manner.

    But instead of accepting that as 1 way to solve the STDIN problem( and is a preferred way on linux, to avoid select and multiple select timeouts), you chose to jump on the Glib module, for some reason, possibly because you don't like it. Probably because it was not designed for Win32 exclusively, which you seem to prefer. Or maybe you don't understand the concept that a snippet may be posted to demonstrate a principle, but not give an exact answer. The Term::Readkey was invoked to read a single key, rather than line input, and was mentioned by the OP, so it is fair to include. Thread::Queue ?? I can't stand that module, but do I respond to your posts advocating it's use as waste and source of problems?

    You said: And if you need to do something that'l take a few seconds, your going to have to break it up into iddy biddy chunks, or lace it through with some do_one_event() call or similar.

    Clearly you havn't read the docs for the Glib module, Idle->add() will add anything you want into the loop one time, you don't need a timer for everything.

    You said:Rubbish! As soon as you enter that MainLoop-run, your main "thread" is dead until something signals stop.

    For as smart as you seem to be in your other answers, you show a complete ignorance of eventloop systems. Maybe you are just having a bad day. My guess is that you are stuck on win32, and don't want to expand your horizons, like most MSjunkies.

    You said: Oh! And what Win32 modules would that be?

    Win32::SocketPair


    I'm not really a human, but I play one on earth Remember How Lucky You Are