Berkeley CSUA MOTD:Entry 36846
Berkeley CSUA MOTD
 
WIKI | FAQ | Tech FAQ
http://csua.com/feed/
2025/07/02 [General] UID:1000 Activity:popular
7/2     

2005/3/24-25 [Computer/SW/Database, Computer/SW/Languages/Perl] UID:36846 Activity:nil Edit_by:auto
3/24    How do I do non-blocking read in Perl? For example, let's say I do
        open(FD, "tail -f file.log |");
        And I'd like to read it, but not block it. Can that be done? -ok thx
        \_ Yes. You need to use fcntl to mark FD as non-blocking and then
           you need to use select and sysread to read from FD.
        \_ http://www.unix.org.ua/orelly/perl/advprog/ch12_03.htm
           http://www.unix.org.ua/orelly/perl/cookbook/ch07_15.htm
           Bottom page, very useful
Open the file with sysopen, and specify the O_NONBLOCK option:
use Fcntl;
sysopen(MODEM, "/dev/cua0", O_NONBLOCK|O_RDWR)
    or die "Can't open modem: $!\n";
If you already have a filehandle, use fcntl to change the flags:
use Fcntl;
$flags = '';
fcntl(HANDLE, F_GETFL, $flags)
    or die "Couldn't get flags for HANDLE : $!\n";
$flags |= O_NONBLOCK;
fcntl(HANDLE, F_SETFL, $flags)
    or die "Couldn't set flags for HANDLE: $!\n";
Once a filehandle is set for non-blocking I/O, the sysread or syswrite calls tha\
t would block will instead return undef and set $! to EAGAIN:
use POSIX qw(:errno_h);
$rv = syswrite(HANDLE, $buffer, length $buffer);
if (!defined($rv) && $! == EAGAIN) {
    # would block
} elsif ($rv != length $buffer) {
    # incomplete write
} else {
    # successfully wrote
}
$rv = sysread(HANDLE, $buffer, $BUFSIZ);
if (!defined($rv) && $! == EAGAIN) {
    # would block
} else {
    # successfully read $rv bytes from HANDLE
}
2025/07/02 [General] UID:1000 Activity:popular
7/2     

You may also be interested in these entries...
2013/4/9-5/18 [Computer/SW/Languages/C_Cplusplus, Computer/SW/Apps, Computer/SW/Languages/Perl] UID:54650 Activity:nil
4/04    Is there a good way to diff 2 files that consist of columns of
        floating point numbers, such that it only tells me if there's a
        difference if the numbers on a given line differ by at least a given
        ratio?  Say, 1%?
        \_ Use Excel.
           1. Open foo.txt in Excel.  It should convert all numbers to cells in
	...
2010/1/22-30 [Computer/HW/Laptop, Computer/SW/OS/OsX] UID:53655 Activity:high
1/22    looking to buy a new development laptop
        needs ssdrive, >6 hr possible batt life, and runs linux reasonably
        Anyone have a recommendation? Thx.
        \_ thinkpad t23 w ssdrive and battery inplace of drive bay
        \_ Ever wondered what RICHARD STALLMAN uses for a laptop?  Well,
           wonder no more!
	...
2009/2/27-3/5 [Computer/Networking] UID:52658 Activity:nil
2/27    I need to buy a wireless router, can u guys help me out?   I need the
        following features:  wireless, G or better, PPTP dial up, PPoE dialup,
        VoIP/SIP register, DDNS, uPnP.
        I am having a such hard time to find a review site which allow me to
        select these features.   Any ideas?  There are a couple model from
        this small company Draytek has these features, I am having the hardest
	...
2008/9/22-29 [Computer/SW/Database] UID:51265 Activity:nil
9/22    In SQL, how can I do something like this:
        SELECT ip_addr, count(*) AS ct FROM table WHERE
          ct > 10 GROUP BY ip_addr?
        I can't get the conditionals to recognize 'ct'
        \_ SELECT ip_addr, count(*) AS ct FROM table HAVING
            count(*) > 10 GROUP BY ip_addr?
	...
Cache (7990 bytes)
www.unix.org.ua/orelly/perl/advprog/ch12_03.htm
The real world is ugly, and you have to resol ve this issue. There are three ways of doing this: 1 Create multiple threads of control (processes or threads) and have ea ch call block in its own thread. We'll call this the "select" approach, because we use the select call to ensure that a socket has something to offer. As we shall see, option 2 should be used in conjunction with option 3 in production systems. In all cases, the client code remains unaffected whi le we try out these options. Some systems support an asynchron ous I/O notification: a SIGIO signal is sent to the process if a specifi ed socket is ready to do I/O. We will not pay attention to this approach because there is no way for a signal handler to know which socket is re ady for reading or writing. The server process acts as a full-time reception ist: it blocks on accept, and when a connection request comes in, it spa wns a child process and goes back to accept. The newly created child pro cess meanwhile has a copy of its parent's environment and shares all ope n file descriptors. Hence it is able to read from, and write to, the new socket returned by accept. When the child is done with the conversation , it simply exits. Each process is therefore dedicated to its own task a nd doesn't interfere with the other. Malcolm Beattie has a working prototype of a threaded Perl interprete r, which will be incorporated into the mainstream in the Perl 5005 rele ase. if ($pid == 0) { # Child process while (defined ($buf = <$new_sock>)) { # do something with $buf .... The parent gets a posit ive return value, the process ID ($pid) of the child process. Both proce sses check this return value and execute their own logic; the main proce ss goes back to accept, and the child process reads a line from the sock et and echoes it back to the client. Incidentally, the CHLD signal has nothing to do with IPC per se. On Unix, when a child process exits (or terminates abnormally), the system gets rid of the memory, files, and other resources associated with it. But it retains a small amount of information (the exit status if the child was able to execute exit(), or a termination status otherwise), just in cas e the parent uses wait or waitpid to enquire about this status. The term inated child process is also known as a zombie process, and it is always a good thing to remove it using wait; otherwise, the process tables kee p filling up with junk. In the preceding code, wait doesn't block, becau se it is called only when we know for sure that a child process has died - the CHLD signal arranges that for us. Be sure to read the online docu mentation for quirks associated with signals in general and SIGCHLD in p articular. We can instead use the selec t call, introduced in BSD Unix, that returns control when a socket (any filehandle, in fact) can be read from or written to. This approach allow s us to use a single-threaded process - somewhat akin to firing the rece ptionist and handling all the incoming calls and conversations ourselves . The interface to the native select call is not very pretty, so we use the IO::Select wrapper module instead. The select met hod (which calls Perl's native select function) accepts three sets of fi lehandles, or IO::Select objects, which are monitored for readability, w ritability, and error conditions, respectively. In the preceding snippet of code, we create two such sets - a filehandle can be added to any or all of these sets if you so wish - and supply them to the select method as follows: ($r_ready, $w_ready, $error) = IO::Select->select($read_set, $write_set, $error_set, $timeout); select blocks until an interesting event occurs (one or more filehandles are ready for reading, writing, or reporting an error condition) or the time-out interval has elapsed. At this point, it creates three separate lists of ready filehandles and returns references to them. The time-out is in seconds but can be expressed as a floating-point number to get mil lisecond resolution. Let us use this information to implement a program that retrieves message s from one or more clients: # Create main socket ($main_socket) as before ... foreach $sock (@$new_readable) { if ($sock == $main_socket) { $new_sock = $sock->accept(); We do the same here, and remove # it from the readable_handles list $readable_handles->remove($sock); We then add this socket to a newly created IO::Selec t collection object. When select returns the first time, $main_socket ha s something to read from (or has an error, a possibility that we ignore for the moment); in other words, it has received a connection request an d is guaranteed not to block when accept is called. Now, we are not inte rested in being blocked if the socket returned from accept has nothing t o say, so we add it to the list of filehandles being monitored for reada bility. When select returns the next time, we know that one of the two s ockets is ready for reading (or both are ready). If $main_socket is read y, we repeat the exercise above. select also returns if one or more remote sockets are closed. The corresp onding sockets on the listening end return 0 when any of the I/O operato rs are used (0 bytes read or written). The server above removes these so ckets from the IO::Select collections to prevent from select returning t he same defunct sockets every time. Unfortunately, we still don't know how much data h as accumulated in the I/O buffers (for purposes of reading) or how much can be written to it (the other side may be reading slowly, and there's a limit to how much you can pump in from this side). Both sysread and sy swrite return the number of bytes actually read or written, so you would have to invoke them in a loop until the entire message is read or writt en. Once you have drained the buffers (or filled them, as the case may b e), there is the very real possibility that it might block the next time you attempt to read or write if the other side doesn't do something qui ck. One option is to invoke select in every iteration of the loop and pr oceed only if it confirms the socket's availability. This slows you down when the filehandle can accommodate your read or write requests. Beside s, you have to quit the loop anyway when select tells you that a filehan dle isn't ready and make the attempt later on when the file descriptor c hanges state. For single-threaded programs the next option is to make the filehandle no n-blocking. The fcntl function takes a command like F_SETFL ( "set flag") and an argument that is specific to that command. Depending on the operating system, the flag to set nonblocking I/O may also be kno wn as O_NDELAY or FNDELAY. In any case, once this operation is carried out, sysread and syswrite ret urn undef (not 0) and set $! to EAGAIN (or EWOULDBLOCK on BSD 43) if th ey cannot carry out the operation right away. The following code account s for these return and error values when reading a socket: # Want to read 1024 bytes $bytes_to_read = 1024; Here we choose to # spin around waiting for something to read. This approach is a constant drain on the CPU because the process is never idle. "Marked by inactivity or repose," as Webster's Tenth Collegiate Dicti onary puts it. You might have noticed that we have ignored clients in all these discussi on. If a client is willing to block, there is no issue at all, since, un like the server side, it is not talking to more than one entity. But if it contains a GUI, it clearly cannot afford to block, and we have much t he same problem. In a system in which there is no clear delineation between "clients" and "servers" - a cluster of bank compute rs is an example of such a peer-to-peer system - every process is modele d on the more general server framework described in the preceding pages. You can now see that all three approaches to creating servers have their individual quirks and failings. The next section introduces us to techni ques and strategies used in typical production servers.
Cache (412 bytes)
www.unix.org.ua/orelly/perl/cookbook/ch07_15.htm
Doing Non-Blocking I/O Problem You want to read from or write to a filehandle without the system blockin g your process until the program, file, socket, or device at the other e nd is ready. This is desired less often of regular files than of special files. Solution Open the file with sysopen, and specify the O_NONBLOCK option: use Fcntl; We use the POSIX module to get the numeric value for t he error EAGAIN.