Search⌘ K

Using select()

Explore how to implement event-based concurrency using the select() API to monitor multiple network sockets for incoming data. Understand the use of FD_ZERO, FD_SET, FD_ISSET macros to manage descriptor sets and how to avoid blocking calls to maintain server responsiveness. This lesson helps you grasp core concepts that prevent concurrency bugs by leveraging single-threaded event-driven server design.

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.

C
#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 loop
while (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 select
int 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. ...