Linux select System Call _1

Source: Internet
Author: User

Synopsis/*according to posix.1-2001*/#include<sys/Select.h>/*according to earlier standards*/#include<sys/time.h>#include<sys/types.h>#include<unistd.h>int Select(intNfds, Fd_set *readfds, Fd_set *Writefds, Fd_set*exceptfds,structTimeval *timeout); voidFD_CLR (intFD, Fd_set *Set); intFd_isset (intFD, Fd_set *Set); voidFd_set (intFD, Fd_set *Set); voidFd_zero (Fd_set *Set);
DESCRIPTION        Select () allow  a  program  to monitor  multiple  file       descriptors,  waiting  Until one or more of the the file descriptors       become'ready' for Class of i/O operation (e.g., input possible).  A file       descriptor  isif possible to perform the corre-        Sponding I/O operation (e.g., read (2)) without blocking.

The SELECT function operates on the data structure fd_set, and Fd_set is a bitmap that consists of open file descriptors.

Note that for pipelines, select is listening by checking to see if the pipe is blocked. As long as the pipe being monitored is non-blocking, select can be immediately informed and set its corresponding 1 in Fd_set. There are only two cases of pipeline non-blocking, one is that the client writes to the pipe, and the other is that the client closes the pipe (read-side). Of course, for non-blocking situations, select can listen, but it does not know if the non-blocking is due to the client shutting down the pipe or the client writing the message to the pipeline. It needs to be judged by ourselves. This is usually judged by the return value of the read system call. Read returns 0, which indicates that the client has closed the pipeline and read returns a positive value, stating that the client is writing to the pipe.

Code

Enables multiple clients to send messages to the server, and the server prints the messages on standard output. The implementation is as follows:

Server.c
/************************************************************************* > File name:server.c > Author: Krischou > Mail:[email protected] > Created time:sat 02:37:58 PM CST ******************************* *****************************************/#include<stdio.h>#include<sys/stat.h>#include<sys/types.h>#include<unistd.h>#include<stdlib.h>#include<string.h>#include<fcntl.h>#include<sys/Select.h>#include<sys/time.h>intMainintargcChar*argv[]) {    /*Open Pipe*/    intfd1, FD2, fd3; FD1= Open (argv[1], o_rdonly); FD2= Open (argv[2], o_rdonly); FD3= Open (argv[3], o_rdonly); printf ("server:%d \ n", Getpid ()); /*sets the collection that the select needs to listen on Fd_set*/fd_set Readset, Bak_set; Fd_zero (&bak_set); Fd_set (FD1,&bak_set); Fd_set (FD2,&bak_set); Fd_set (FD3,&bak_set); /*Set Select round Patrol Time*/    structTimeval TM; Tm.tv_sec=Ten ; Tm.tv_usec=0 ; /*You can start the program and allow the server to read 3 messages at a time, which is optional*/Sleep (Ten); /*Select is monitored by checking to see if the pipe is blocked.     If both are blocked, select returns 0 within the patrol time.     * If a pipeline does not block, select returns the number of pipes that are not blocked.     * Note: When a client sends data to a pipeline, or shuts down a pipeline, it is non-blocking. * We can distinguish between the two cases based on the return value of Read*/    intNret;/*Select return value*/    Charbuf[1024x768];  while(1){        /*The value of the Listen collection for select is changed after each select, so you need to reset the listening collection at the start of each select.         * If not set, the descriptor for listener set 1 after the last select is still 1.                                            * Note: The time also needs to be reset under the Linux system. */Readset=Bak_set; Tm.tv_sec=Ten ; Tm.tv_usec=0 ; Nret=Select(6, &readset, NULL, NULL, &TM); if(Nret >0) {printf ("%d active! \ n", Nret); if(Fd_isset (FD1, &readset))/*when the Select return value is greater than 0 o'clock, there must be a pipeline that does not block, and you need to see which pipe*/{memset (buf,0,1024x768); if(0= = Read (FD1, buf,1024x768) {fd_clr (FD1,&bak_set);/*If a user whose write end is closed, remove its descriptor from the Listener collection*/                }Else{Write (1, buf, strlen (BUF)); }            }            if(Fd_isset (FD2, &Readset)) {memset (buf,0,1024x768); if(0= = Read (FD2, buf,1024x768) {fd_clr (FD2,&bak_set); }Else{Write (1, buf, strlen (BUF)); }            }            if(Fd_isset (FD3, &Readset)) {memset (buf,0,1024x768); if(Read (FD3, buf,1024x768) ==0) {fd_clr (fd3,&bak_set); }Else{Write (1, buf, strlen (BUF)); }            }        }Else if(Nret = =0) {printf ("Time Out ! \ n"); }    }
}
Client.c
/************************************************************************* > File name:client.c > Author:k Rischou > Mail:[email protected] > Created time:sat 02:30:54 PM CST **************************** ********************************************/#include<stdio.h>#include<stdlib.h>#include<string.h>#include<sys/types.h>#include<sys/stat.h>#include<fcntl.h>#include<unistd.h>#include<time.h>intMainintargcChar*argv[]) {    /*Open Pipe*/printf ("%d start! \ n", Getpid ()); intfd_sent; Fd_sent= Open (argv[1],o_wronly); if(Fd_sent = =-1) {perror ("Open"); Exit (1); } printf ("connect success! \ n"); /*the client sends a message to the pipeline, pressing Ctrl+d to exit the loop*/        Charline[1024x768];/*get the message to send from standard input*/    Charmsg[1024x768];/*add a PID to the message header to indicate identity*/         while(Memset (line,0,1024x768), Fgets (line,1024x768, stdin)! =NULL) {memset (msg,0,1024x768); sprintf (MSG,"%d:%s \ n", Getpid (), line);    Write (Fd_sent, MSG, strlen (msg));    } close (fd_sent); return 0;}

Execute the program:

1 2 3 . FIFO;
. 1 2 3 . FIFO
. 1 . FIFO. 2 . FIFO. 3. FIFO
Note 1

If you remove the following code:

if (01024x768)) {    &bak_set);     /* */}

FD2 and Fd3 also remove, then the program runs, will fall into a dead loop. The reasons are as follows: We assume that the client shuts down the pipe 1.fifo, then select will listen to 1.fifo non-blocking, execute the IF statement in the while loop, and detect that the FD1 is non-blocking (because the client shuts down the pipeline at the end of the write), then execute write ( 1, buf, strlen (BUF)); Because buf is empty, nothing is output. At this point, because the while (1) dead Loop, select and then listen, because the FD1 is not removed from the listening set, select immediately to listen to its non-blocking ... So the cycle, into the dead loop. When a client closes the write end, after exiting, the program outputs the result:

1 active! 1 active! 1 active! ...
NOTE 2

If you do not force exit, the server program will never exit. The client can close the pipe exit. You can also open the pipeline and connect to the server after shutting down.

Linux select System Call _1

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.