Linux select System Call _ 1, select System Call _ 1

Source: Internet
Author: User

Linux select System Call _ 1, select System Call _ 1

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(int nfds, fd_set *readfds, fd_set *writefds,                  fd_set *exceptfds, struct timeval *timeout);       void FD_CLR(int fd, fd_set *set);       int  FD_ISSET(int fd, fd_set *set);       void FD_SET(int fd, fd_set *set);       void FD_ZERO(fd_set *set);
DESCRIPTION       select() allow  a  program  to  monitor  multiple  file       descriptors,  waiting  until one or more of the file descriptors become       "ready" for some class of I/O operation (e.g., input possible).  A file       descriptor  is considered ready if it is 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. fd_set is a bitmap that consists of open file descriptors.

Note: For MPs queues, select performs monitoring by checking whether the MPs queue is blocked. As long as the pipeline to be monitored is not blocked, select can immediately learn and set it to 1 in fd_set. There are only two scenarios for non-blocking pipelines. One is that the client writes something to the pipeline, and the other is that the client closes the pipeline (read end ). Of course, for non-blocking situations, select can listen, but it does not know whether the non-blocking is because the client closes the pipeline or the client writes messages to the pipeline. We need to determine this by ourselves. It is usually determined by the return value of the read system call. If 0 is returned for read, the client closes the MPs queue and returns a positive value for read, indicating that the client has written something to the MPs queue.

Maybe you will have such a question: if there are n clients, then we can not fork out n-1 sub-processes, a total of n processes, used to receive client messages? In fact, this is not feasible, because one program can only open up to 1024 processes. Therefore, it is reasonable to use select here.

Code

Multiple clients send messages to the server. The server prints messages to the standard output. If there are three clients, three pipelines are created in advance, and each client uses one pipeline to send messages to the server. When the select system is called on the server side, the server reads a message from a certain pipeline and displays it on the standard output. The implementation is as follows:

Server. c
/*************************************** * *********************************> File Name: server. c> Author: KrisChou> Mail: zhoujx0219@163.com> Created Time: sat 23 Aug 2014 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> # I Nclude <sys/select. h> # include <sys/time. h> int main (int argc, char * argv []) {/* open Pipeline */int fd1, 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 ()); /* Set 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);/* sets the select round time */struct Timeval tm; tm. TV _sec = 10; tm. TV _usec = 0;/* you can start the program so that the server can read three messages at the same time. */sleep (10) is optional./* select checks whether the pipeline is blocked,. If both are blocked, select returns 0 within the round robin time. * If a media transcoding queue is not blocked, select returns the number of media transcoding queues that are not blocked. * Note: When a client sends data to or closes a media transcoding queue, It is not blocked. * We can distinguish the two cases based on the read return values */int nret;/* select return values */char buf [1024]; while (1) {/* Each select Operation changes the value of the Set listened to by the select statement. Therefore, you need to reset the set at the beginning of each select statement. * If this parameter is not set, the descriptor set to 1 in the listening set after the last select operation is still 1. * Note: in Linux, the time needs to be reset. */Readset = bak_set; tm. TV _sec = 10; 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 return value of select is greater than 0, pipelines are not blocked, in this case, you need to check which Pipeline */{memset (buf, 0, 1024); if (0 = read (fd1, buf, 1024) {FD_CLR (fd1, & bak_set);/* if a user's write end has been disabled, remove its descriptor from the listening Set */} else {write (1, buf, strlen (buf) ;}} if (FD_ISSET (fd2, & readset) {memset (buf, 0, 1024); if (0 = read (fd2, buf, 1024) {FD_CLR (fd2, & bak_set) ;}else {write (1, buf, strlen (buf) ;}} if (FD_ISSET (fd 3, & readset) {memset (buf, 0, 1024); if (read (fd3, buf, 1024) = 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: KrisChou> Mail: zhoujx0219@163.com> Created Time: sat 23 Aug 2014 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> # I Nclude <time. h> int main (int argc, char * argv []) {/* enable Pipeline */printf ("% d start! \ N ", getpid (); int fd_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, and press ctrl + D to exit the loop */char line [1024]; /* obtain the message to be sent from the standard input */char msg [1024];/* Add a pid to the message header, indicating the identity */while (memset (line ), fgets (line, 1024, stdin )! = NULL) {memset (msg, 0,1024); sprintf (msg, "% d: % s \ n", getpid (), line); write (fd_sent, msg, strlen (msg);} close (fd_sent); return 0 ;}

Execution program:

mkfifo 1.fifo 2.fifo 3.fifo;
./server.exe 1.fifo 2.fifo 3.fifo
./client 1.fifo./client 2.fifo./client 3.fifo
Note 1

Remove the following code:

If (0 = read (fd1, buf, 1024) {FD_CLR (fd1, & bak_set);/* if a user's write end has been disabled, remove its descriptor from the listener Set */}

If both fd2 and fd3 are removed, the program runs and runs into an endless loop. The reason is as follows: assume that the client closes the MPs queue. fifo, select will listen to 1. if the fifo is not blocked, the if statement in the while loop is executed, and fd1 is not blocked (because the client closes the pipeline at the write end), The write (1, buf, strlen (buf); because the buf is empty, nothing is output. At this time, because while (1) is an endless loop, select then listens. Because fd1 is not removed from the listener set, select immediately listens to its non-blocking... This cycle repeats and falls into an endless loop. When a client closes the write end and exits, the output result of the program is:

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 MPs queue and exit. You can also enable the MPs queue and connect it to the server.


A question about the select system call

/* The following programs have been successfully debugged on ubutun linux g ++. Using the linked list + SELECT () method, the single-threaded single process achieves I/O multiplexing technology, it is more concise than the original system */
# Include <arpa/inet. h>
# Include <errno. h>
# Include <netinet/in. h>
# Include <stdio. h>
# Include <stdlib. h>
# Include <string. h>
# Include <sys/io. h>
# Include <sys/stat. h>
# Include <sys/socket. h>
# Include <sys/time. h>
# Include <sys/times. h>
# Include <sys/types. h>
# Include <sys/wait. h>
# Include <time. h>
# Include <unistd. h>
# Define szBUF 1024

Int do_listen (const int port, const int bTcp)
{
Int s = 0, r = 0, o = 1;
Struct sockaddr_in h;
Memset (& h, 0, sizeof (h ));
H. sin_family = AF_INET; h. sin_port = htons (port );
H. sin_addr.s_addr = INADDR_ANY;
S = socket (AF_INET, bTcp? SOCK_STREAM: SOCK_DGRAM, 0 );
If (s <1) {perror ("socket (listen)"); return 0 ;}
R = setsockopt (s, SOL_SOCKET, SO_REUSEADDR, (char *) & o, sizeof (int ));
If (r =-1) {perror ("setsockopt (listen)"); return 0 ;}
R = bind (s, (struct sockaddr *) & h, sizeof (h ));
If (r =-1) {perror ("bind (listen)"); return 0 ;}
If (bTcp ){
R = listen (s, SOMAXCONN );
If (r =-1) {perror ("listen ()"); return 0 ;}
}/* End if */
Return s;
}/* End do_listen */

Typedef struct CLIENTS {
Int s;
Struct CLIENTS * next;
} CL;
CL * locate (CL * head, int sock)
{CL * h = head; while (h) {if (h-> s = sock) return h; h = h-> next;} return 0 ;}

Void append (CL ** head,... the remaining full text>

Use of select in linux

The select () function modifies the value of the variable TV. You need to set TV again before calling the select () function.
Or you can use pselect ()

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.