Poll is a mechanism for monitoring whether a file is readable, as with select.
The calling function for the application is as follows:
int poll (struct POLLFD *fds,nfds_t nfds, int timeout);
The poll mechanism will determine whether the file in the FDS is readable, if it is readable, it returns immediately, the value returned is the number of readable FD, if it is unreadable, then the process will hibernate timeout for such a long time, and then to determine whether there is a file readable, if any, return the number of FD, if not, then return 0 .
Applications that use non-blocking I/O typically use the Select () and poll () system call queries for non-blocking access to the device, which eventually causes the poll () function in the device driver to be executed
If the current non-readable (call driver. Poll determines whether it is readable and then continues to Do_poll), the current process in Sys_poll->do_poll will sleep on the waiting queue, which is provided by the driver (that is, Poll_ The one that was passed in wait). When readable, the driver may have a portion of the code running (such as a driven interrupt service
program), then in this part of the code, it wakes up the process on the waiting queue, that is, the one before sleep, and when that process is awakened, Do_poll will call the driver's poll function again, and this time the application will know it is readable.
Demo program (one thread simultaneously listens to two UDP client program data send):
#include <sys/types.h>#include<sys/socket.h>#include<netinet/inch.h>#include<stdio.h>#include<string.h>#include<unistd.h>#include<stdlib.h>#include<errno.h>///Handle Poll input Types#definePoll_input (Pollin | POLLPRI)///Handle Poll Error Types#definePoll_error (Pollerr | Pollhup | Pollnval)///Handle Pool Output Types#definePoll_output (Pollout)///Identify each physical interfacetypedefenumfhandleval{INTERFACE_UDP_DCP=0, Interface_udp_lte, Interface_max_val}efhandleval;Static structPOLLFD Fdesc[interface_max_val];Static intrxudplteinit ();Static intrxudpdcpinit ();Static intRxlteudpdata (intFD);Static intRxdcpudpdata (intFD);intRxudplteinit () {structsockaddr_in server_lte_addr; ///UDP Datagram Socket intSOCK_LTE_FD =sockets (Af_inet, SOCK_DGRAM, IPPROTO_UDP); if(Sock_lte_fd <0) { //oopsprintf"UDP lte:rx socket failed%d,%s\n", errno, Strerror (errno)); SOCK_LTE_FD= -errno; return-1; } memset (&SERVER_LTE_ADDR,0,sizeof(structsockaddr_in)); Server_lte_addr.sin_family=af_inet; Server_lte_addr.sin_addr.s_addr=htonl (Inaddr_any); Server_lte_addr.sin_port= Htons (27358); intrc = Bind (SOCK_LTE_FD, (structSOCKADDR *) &server_lte_addr,sizeof(SERVER_LTE_ADDR)); if(RC <0) { //oopsprintf"Udp:bind (%d, any) RX failed:%d,%s\n", SOCK_LTE_FD, errno, Strerror (errno)); Close (SOCK_LTE_FD); SOCK_LTE_FD= -errno; } Else{printf ("udp:bind on RX Port%d\n",27358); } returnsock_lte_fd; }intRxudpdcpinit () {intsock_fd; structsockaddr_in server_addr; structsockaddr_in src_addr; Socklen_t Client_len; memset (&SERVER_ADDR,0,sizeof(structsockaddr_in)); if(SOCK_FD = socket (af_inet, SOCK_DGRAM,0)) <0) {perror ("Socket Create error\n"); Exit (1); } server_addr.sin_family=af_inet; Server_addr.sin_port= Htons (4004); Server_addr.sin_addr.s_addr=htonl (Inaddr_any); printf ("Ready bind 4004\n"); if(Bind (SOCK_FD, (structSOCKADDR *) &server_addr,sizeof(structsockaddr_in)) <0) {perror ("bind socket error.\n"); Exit (1); } returnsock_fd;}intRxdcpudpdata (intFD) { intRcv_num =-1; Charrcv_buff[ +]; structsockaddr_in src_addr; Socklen_t Client_len; intEncodenum =-1; Bsm_t Bsmdata; Client_len=sizeof(structsockaddr_in); Rcv_num= Recvfrom (FD, Rcv_buff,sizeof(Rcv_buff),0, (structsockaddr*) &src_addr, &Client_len); if(rcv_num>0) {Rcv_buff[rcv_num]=' /'; printf ("%s%d says:%s\n", Inet_ntoa (SRC_ADDR.SIN_ADDR), Ntohs (Src_addr.sin_port), rcv_buff); } Else{perror ("recv DCP Data error\n"); Exit (1); } return 0;} intRxlteudpdata (intFD) { intRcv_num =-1; Charrcv_buff[ +]; structsockaddr_in src_addr; Socklen_t Client_len; Client_len=sizeof(structsockaddr_in); Rcv_num= Recvfrom (FD, Rcv_buff,sizeof(Rcv_buff),0, (structsockaddr*) &src_addr, &Client_len); if(rcv_num>0) {Rcv_buff[rcv_num]=' /'; printf ("%s%d says:%s\n", Inet_ntoa (SRC_ADDR.SIN_ADDR), Ntohs (Src_addr.sin_port), rcv_buff); }Else{perror ("recv lte-v Data Error:"); Exit (1); }}intMainvoid) {FDESC[INTERFACE_UDP_LTE].FD=Rxudplteinit (); if(Fdesc[interface_udp_lte].fd <0) Exit (1); FDESC[INTERFACE_UDP_DCP].FD=Rxudpdcpinit (); if(Fdesc[interface_udp_dcp].fd <0) Exit (1); //Setup The poll eventsFdesc[interface_udp_dcp].events =Poll_input; Fdesc[interface_udp_lte].events=Poll_input; while(1) { intData = Poll (Fdesc, Interface_max_val, +); //Poll Status Check if(Data <0) { //Errorprintf"Poll error%d '%s ' \ n", errno, Strerror (errno)); } Else if(Data = =0) { //Timeoutprintf"Poll timeout\n"); Continue; } //Receive DCP UDP if(Fdesc[interface_udp_dcp].revents &poll_error) {printf ("Poll error on UDP (revents 0x%02x) \ n", fdesc[interface_udp_dcp].revents); } if(Fdesc[interface_udp_dcp].revents &poll_input) { intRes =Rxdcpudpdata (FDESC[INTERFACE_UDP_DCP].FD); if(res!=0) { } } //Receive LTE UDP if(Fdesc[interface_udp_lte].revents &poll_error) {printf ("Poll error on UDP (revents 0x%02x) \ n", fdesc[interface_udp_lte].revents); } if(Fdesc[interface_udp_lte].revents &poll_input) { intRes =Rxlteudpdata (FDESC[INTERFACE_UDP_LTE].FD); } } if(FDESC[INTERFACE_UDP_LTE].FD) Close (FDESC[INTERFACE_UDP_LTE].FD); if(FDESC[INTERFACE_UDP_DCP].FD) Close (FDESC[INTERFACE_UDP_DCP].FD); return 0;}
Linux C-poll Example