Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Non-blocking socket with poll

A couple of days ago I had to investigate a problem where my application was showing abnormally high CPU usage when it was (apparently) in idle state. I tracked the problem down to a loop which was meant to block on a recvfrom call while the socket had been set to O_NONBLOCK-ing resulting in a spin lock. There were two ways of solving the problem: set the socket to blocking or poll for available data on the socket using poll or select. I chose the former as it was simpler. But I am wondering why any one would create a non-blocking socket and then poll on it separately. Doesn't a blocking socket do the same? What are the uses cases where one would use a non-blocking socket and poll combination? Are there any advantages to it in general cases?

like image 247
341008 Avatar asked Jul 29 '10 08:07

341008


People also ask

What is poll in socket programming?

The poll() API allows simultaneous connection with all descriptors in the queue on the listening socket. The accept() and recv() APIs are completed when the EWOULDBLOCK is returned. The send() API echoes the data back to the client. The close() API closes any open socket descriptors.

How do I make a socket non-blocking?

To mark a socket as non-blocking, we use the fcntl system call. Here's an example: int flags = guard(fcntl(socket_fd, F_GETFL), "could not get file flags"); guard(fcntl(socket_fd, F_SETFL, flags | O_NONBLOCK), "could not set file flags"); Here's a complete example.

How can you tell if a socket is blocking or non-blocking?

From MSDN, the return value of connect(): On a blocking socket, the return value indicates success or failure of the connection attempt. With a nonblocking socket, the connection attempt cannot be completed immediately. In this case, connect will return SOCKET_ERROR , and WSAGetLastError() will return WSAEWOULDBLOCK.

What is the difference between select and poll in polling method?

The select() call has you create three bitmasks to mark which sockets and file descriptors you want to watch for reading, writing, and errors, and then the operating system marks which ones in fact have had some kind of activity; poll() has you create a list of descriptor IDs, and the operating system marks each of ...


1 Answers

Using poll() or select() with a non-blocking file descriptor gives you two advantages:

  • You can set a timeout to block for;
  • You can wait for any of a set of file descriptors to become useable.

If you only have a single file descriptor (socket) to wait for, and you don't mind waiting indefinitely on it, then yes; you can just use a blocking call.

The second advantage is really the killer use case for select() and friends. It means that you can handle multiple socket connections, as well as standard input and standard output and possibly file I/O, all with a single thread of control.

like image 61
caf Avatar answered Oct 08 '22 03:10

caf