Using select()
This lesson presents an example to explain the usage of select().
We'll cover the following
To make this more concrete, let’s examine how to use select()
to see which network descriptors have incoming messages upon them. The code excerpt below shows a simple example.
#include <stdio.h>#include <stdlib.h>#include <sys/time.h>#include <sys/types.h>#include <unistd.h>int main(void) {// open and set up a bunch of sockets (not shown)// main loopwhile (1) {// initialize the fd_set to all zero fd_set readFDs;fd_set readFDs;FD_ZERO(&readFDs);// now set the bits for the descriptors// this server is interested in// (for simplicity, all of them from min to max)int fd;for (fd = minFD; fd < maxFD; fd++)FD_SET(fd, &readFDs);// do the selectint rc = select(maxFD+1, &readFDs, NULL, NULL, NULL);// check which actually have data using FD_ISSET()int fd;for (fd = minFD; fd < maxFD; fd++)if (FD_ISSET(fd, &readFDs))processFD(fd);}}
This code is actually fairly simple to understand. After some initialization, the server enters an infinite loop. Inside the loop, it uses the FD_ZERO()
macro to first clear the set of file descriptors and then uses FD_SET()
to include all of the file descriptors from minFD
to maxFD
in the set. This set of descriptors might represent, for example, all of the network sockets to which the server is paying attention. Finally, the server calls select()
to see which of the connections have data available upon them. By then using FD_ISSET()
in a loop, the event server can see which of the descriptors have data ready and process the incoming data.
Of course, a real server would be more complicated than this and require logic to use when sending messages, issuing disk I/O, and many other details. For further information, see
TIP: DON’T BLOCK IN EVENT-BASED SERVERS
Event-based servers enable fine-grained control over scheduling of tasks. However, to maintain such control, no call that blocks the execution of the caller can ever be made. Failing to obey this design tip will result in a blocked event-based server, frustrated clients, and serious questions as to whether you ever read this part of the course.
Why Simpler? No Locks Needed
With a single CPU and an event-based application, the problems found in concurrent programs are no longer present. Specifically, because only one event is being handled at a time, there is no need to acquire or release locks; the event-based server cannot be interrupted by another thread because it is decidedly single-threaded. Thus, concurrency bugs common in threaded programs do not manifest in the basic event-based approach.
Get hands-on with 1400+ tech skills courses.