Concurrent IO solutions: multi-channel non-blocking IO, multiplexing, asynchronous IO, multiplexing io
Three methods of concurrent I/O in Linux application programming are:
(1) multi-channel non-blocking IO
(2) multiplexing
(3) asynchronous IO
The following code uses the mouse and keyboard as an example.
1. Multi-channel non-blocking IO
Multi-channel non-blocking I/O access, mainly adding the O_NONBLOCK flag and fcntl () function.
Sample Code:
1/* 2 * concurrent I/O solution 1: multi-channel non-blocking I/O processing keyboard and mouse simultaneously read 3 */4 5 # include <stdio. h> 6 # include <unistd. h> 7 # include <string. h> 8 # include <fcntl. h> 9 # include <sys/types. h> 10 # include <sys/stat. h> 11 12 # define MOUSEPATH "/dev/input/mouse1" 13 14 int main (void) 15 {16 int fd =-1; 17 int ret =-1; 18 int flag =-1; 19 char buf [200] = {0}; 20 21 fd = open (MOUSEPATH, O_RDONLY | O_NONBLOCK); 22 if (fd <0) 23 {24 perror ("open"); 25 _ exit (-1 ); 26} 27 28 // convert the 0 file descriptor into a non-blocking 29 flag = fcntl (0, F_GETFD); // obtain the original flag30 flag of stdin | = O_NONBLOCK; // Add the non-blocking attribute 31 fcntl (0, F_SETFL, flag) to the original flag of stdin; // update flag32 33 while (1) 34 {35 // read the mouse 36 memset (buf, 0, sizeof (buf); 37 ret = read (fd, buf, 50); 38 39 if (ret> 0) 40 {41 printf ("the content read by the mouse is: [% s] \ n", buf); 42} 43 44 // read the keyboard 45 memset (buf, 0, sizeof (buf); 46 ret = read (0, buf, 50); 47 if (ret> 0) 48 {49 printf ("the content read by the keyboard is: [% s] \ n ", buf); 50} 51} 52 53 return 0; 54}
2. IO multiplexing
(1) multi-channel non-blocking IO
(2) select () and poll () Functions
(3) External blocking, internal non-blocking automatic round robin multiple-channel blocking IO
Sample Code:
Select () function implementation:
1/* 2 * concurrent IO solution 2: multiplexing select () function processing 3 */4 5 # include <stdio. h> 6 # include <string. h> 7 # include <unistd. h> 8 # include <sys/types. h> 9 # include <sys/stat. h> 10 # include <fcntl. h> 11 # include <sys/select. h> 12 # include <sys/time. h> 13 # include <stdlib. h> 14 15 # define MOUSEPATH "/dev/input/mouse1" 16 17 int main (void) 18 {19 int fd =-1, ret =-1; 20 char buf [300] = {0}; 21 fd_set myset; 22 struct timeval tmv; 23 24 fd = open (MOUSEPATH, O_RDONLY); 25 if (-1 = fd) 26 {27 perror ("open"); 28 _ exit (-1); 29} 30 31 // process myset32 FD_ZERO (& myset); // clear 33 FD_SET (fd, & myset); // load the file descriptor of the mouse to 34 FD_SET (0, & myset) in the myset set; 35 36 // struct timeval * timeout processing 37 tmv. TV _sec = 10; 38 tmv. TV _usec = 0; 39 40 // prototype: int select (int nfds, fd_set * readfds, fd_set * writefds, fd_set * exceptfds, struct timeval * timeout ); 41 ret = select (fd + 1, & myset, NULL, NULL, & tmv ); // fd + 1 here is the largest fd plus 1 nfds is 42 from 0 if (ret <0) 43 {44 perror ("select "); 45 _ exit (-1); 46} 47 else if (ret = 0) 48 {49 printf ("Timeout. \ n "); 50 exit (0); 51} 52 else53 {54/* waited for one IO, then monitor which IO will be processed */55 if (FD_ISSET (fd, & myset) 56 {57 // here processing the mouse 58 memset (buf, 0, sizeof (buf); 59 read (fd, buf, 50); 60 printf ("the content read by the mouse is: [% s] \ n", buf ); 61} 62 63 if (FD_ISSET (0, & myset) 64 {65 // here handle keyboard 66 memset (buf, 0, sizeof (buf); 67 read (0, buf, 50); 68 printf ("the content read by the keyboard is: [% s] \ n", buf); 69} 70} 71 72 return 0; 73}
Poll () function implementation:
1/* 2 * concurrent IO solution 2: multiplexing poll () function processing 3 */4 5 # include <stdio. h> 6 # include <string. h> 7 # include <unistd. h> 8 # include <sys/types. h> 9 # include <sys/stat. h> 10 # include <fcntl. h> 11 # include <poll. h> 12 # include <stdlib. h> 13 14 # define MOUSEPATH "/dev/input/mouse1" 15 # define IO_MULTIPLEXING 216 # define MAXBUF 102417 # define MILLISECOND 100018 19 int main (void) 20 {21 int fd =-1, ret =-1, I = 0; 22 char buf [MAXBUF] = {0 }; 23 struct pollfd pfd [IO_MULTIPLEXING] = {0}; 24 25 fd = open (MOUSEPATH, O_RDONLY); 26 if (-1 = fd) 27 {28 perror ("open"); 29 _ exit (-1); 30} 31 32 // initialize pollfd33 pfd [0]. fd = 0; // keyboard 34 pfd [0]. events = POLLIN; // wait for the read operation 35 36 pfd [1]. fd = fd; // keyboard 37 pfd [1]. events = POLLIN; // wait for the read operation to 38 39 // prototype: int poll (struct pollfd * fds, nfds_t nfds, int timeout); 40 ret = poll (pfd, fd + 1, 10 * MILLISECOND); // fd + 1 here is the largest fd plus 1 nfds is 41 from 0 if (ret <0) 42 {43 perror ("poll"); 44 _ exit (-1); 45} 46 else if (ret = 0) 47 {48 printf ("Timeout. \ n "); 49 exit (0); 50} 51 else52 {53/* waited for one IO, then monitor which IO is processed when I arrive */54 for (I = 0; I <IO_MULTIPLEXING; I ++) 55 {56 // handle keyboard and mouse 57 if (pfd [I]. events = pfd [I]. revents) 58 {59 memset (buf, 0, sizeof (buf); 60 read (pfd [I]. fd, buf, MAXBUF); 61 printf ("Content: [% s]. \ n ", buf); 62} 63} 64} 65 66 close (fd); 67 68 return 0; 69}
3. asynchronous IO
(1) asynchronous IO: an interrupt response system implemented by the operating system using software.
(2) working method: the process registers an asynchronous IO event (use signal to register a processing function for signal SIGIO)
(3) involved functions: fcntl (F_GETFL, F_SETFL, O_ASYNC, F_SETOWN), signal (), sigaction () Functions
Sample Code:
1/* 2 * concurrent IO solution 3: asynchronous IO processing signal or sigaction and fcntl 3 */4 5 # include <stdio. h> 6 # include <sys/types. h> 7 # include <sys/stat. h> 8 # include <fcntl. h> 9 # include <unistd. h> 10 # include <signal. h> 11 # include <string. h> 12 13 # define MAXBUFF 1024 14 # define MOUSEPATH "/dev/input/mouse1" 15 16 // global configuration 17 int mousefd =-1; 18 19 // define the signal function pointer 20 typedef void (* sighandler_t) (int); 21 22 // function declaration 23 void Func (int sig); 24 25 int main (void) 26 {27 int flag =-1; 28 char buf [MAXBUFF]; 29 sighandler_t ret = (sighandler_t)-2; 30 31 // manipulate the mouse file 32 mousefd = open (MOUSEPATH, O_RDONLY); 33 if (mousefd <0) 34 {35 perror ("open "); 36 _ exit (-1); 37} 38 39 // set the file descriptor of the mouse to asynchronous IO40 flag = fcntl (mousefd, F_GETFL); 41 flag | = O_ASYNC; 42 fcntl (mousefd, F_SETFL, flag); 43 44 // set the receiving process of asynchronous IO events to the current process 45 fcntl (mousefd, F_SETOWN, Getpid (); 46 47 // register the SIGIO signal capture function of the current process 48 ret = signal (SIGIO, func); 49 if (SIG_ERR = ret) 50 {51 perror ("signal"); 52 _ exit (-1); 53} 54 // operation keyboard 56 while (1) 57 {58 memset (buf, 0, sizeof (buf); 59 read (0, buf, MAXBUFF); 60 printf ("the content read by the keyboard is: [% s]. \ n ", buf); 61} 62 63 return 0; 64} 65 66 // bind to SIGIO signal, process asynchronous notification event 67 void func (int sig) in the function) 68 {69 char buf [MAXBUFF] = {0}; 70 71 if (sig! = SIGIO) 72 return; 73 74 read (mousefd, buf, MAXBUFF); 75 printf ("the content read by the mouse is: [% s]. \ n ", buf); 76}