in reply to Re: How to Multiplex a Client using IO::Select
in thread How to Multiplex a Client using IO::Select

First of all thanks for your reply. I will look through links your provided. POE is good idea but the modules is very huge enough to sit in memory constrains applications devices.So i planned to write of my own server and client that suits for my application. Pblm with select is that its behavior is different for platform like Windows and Linux. One example is, STDIN won't work in Windows with select. This has been explained in Network Programming with Perl by Lincoln D. Stein many years back. Over these years any solution has been found for that or i don't know(If there pls provide link for the same). I want to design a platform independent server and client. Provide me if any other way of multitasking.without forks or thread(both has drawback as memory usage. Any other go for memory constrain applications.(or only option is select??).
  • Comment on Re^2: How to Multiplex a Client using IO::Select

Replies are listed 'Best First'.
Re^3: How to Multiplex a Client using IO::Select
by BrowserUk (Patriarch) on Oct 12, 2008 at 13:23 UTC
    One example is, STDIN won't work in Windows with select

    So don't insist that everything is selectable. Use select on the sockets which is portable, and use a thread for STDIN. There is only 1 STDIN, so the cost is minimal.

    Your main dispatch loop then becomes something like:

    my $Qstdin = new Thread::Queue; async { $Qstdin->enqueue( $_ ) while defined( $_ = <STDIN> ); }->detach; ... while( 1 ) { if( my @readers = $selector->can_read( 0.1 ) ) { ## See what they have to say } elsif( my @writers = $selector->can_write( 0.1 ) { ## Tell'em what they need to know } elsif( my @exceptors = $selector->has_exception( 0.1 ) { ## Deal with their tantrums } else { while( $Qstdin->pending ) { my $kbinput = $Qstdin->dequeue; ## do whatever } } }

    That should be portable to any OS supporting threads:

    • It uses one thread, so memory use is minimal.
    • It requires no user locking or syncing. Simple code.
    • Doesn't require you to do nasty things like using RAW mode.

      That means that all the facilties provided by the local shell, like:

      • Line buffering.
      • Line editing.
      • History.
      • Macro expansion.
      • Redirection.
      • etc.

      are available without any extra effort, code or complications on your behalf.


    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.

      The second and third timeout should be zero. Better yet, you can combine the three system calls into one:

      while( 1 ) { if ( my ($readers, $writers, $exceptors) = IO::Select::select($selector, $selector, $selector, 0.1) ) { for( @$readers ) { ## See what they have to say } for( @$writers ) { ## Tell'em what they need to know } for( @$exceptors ) { ## Deal with their tantrums } } if( $Qstdin->pending ) { my $kbinput = $Qstdin->dequeue; ## do whatever } }

      Another possible improvement would be to ditch Thread::Queue in favour of a Win32::Socketpair "pipe".

        Another possible improvement would be to ditch Thread::Queue in favour of a Win32::Socketpair "pipe".

        I'd be very reluctant to give up what I know works in favour of something, that despite my recognising it's promise, I've yet to get to grips with. Have you tried Win32::Socketpair yet?

        From my view it just adds complications. You still need a thread to handle STDIN, but now you have the problem of passing socket handles around? How would you construct the above snippet?


        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.
      my $Qstdin = new Thread::Queue; async { $Qstdin->enqueue( $_ ) while defined( $_ = <STDIN> ); }->detach; In this code while waits for input. when does the thread context switch to while(1) loop??. It is looping in while defined ($_ = <STDIN>)

        The following code runs the thread asynchronously and detached:

        async { ... }->detach();

        This starts a separate thread that will read from STDIN and stuff the input into the queue.

      Ya it is very good idea. I will try with it. Above code snippet is in while 1 loop how does the can_read or selection would know the service has disconnected.. Whether has_exception will take care of it??(will try it). Command on that.

        On disconnect, can_read is triggered. Attempting to read will return 0.

        Update: Alternatively, eof should return true.