开发者

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 proble开发者_JAVA百科m 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?


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.


I´m posting here, because although the question is old. It came up in my google search somehow and has definitely not been answered properly.

The accepted answer merely highlights two advantages of using non-blocking sockets but does not really go into detail or answer the actual question.

  • NOTE : Unfortunately most online "tutorials" or code snippets only feature blocking socket code, so knowledge on non-blocking sockets is less spread.

As to when you would you use one compared to the other ... in general blocking sockets are only used in online code snippets. In all (good) production applications non-blocking sockets are used. I´m not ignorant, if you know of an implementation that uses blocking sockets (and sure that´s very well possible in combination with threads) - or let´s be more specific that uses blocking sockets in a single thread - please do let me know.

Now I can give you a very easy to understand example, and there are many others out there. Let´s take the example of a gaming server. Games advances at ticks, regular intervals where the game state progresses whether or not the player provides input (mouse / keyboard) to change the state of the game. Now when sockets come into play in Multiplayer games - if you were to use blocking sockets the game state would not advance unless the players were sending updates - so if they have internet problems, the game state would never consistently update and propagate changes to all players. You would have a rather choppy experience.

Now using non-blocking sockets, you can run the gameserver on a single-thread, updating the gamestate as well as the sockets, with a ... let´s say 50ms timeout interval - and socket data is only read from connected users when they actually send something, and then fed into the server simulation, processed and fed into the game state calculation for the next tick.


resulting in a spin lock.

That condition normally is called a tight loop.

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.

Are you sure that other code parts do not already use poll() (or select()) and expect the socket to be in non-blocking mode?

Otherwise, then yes, the switch to the blocking mode is the simplest solution.

Best backward-compatible solution would have been before calling recvfrom() to use poll() to wait for the socket to become readable. That way ensures that other parts of the code would work precisely as before.

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?

For the case of recvfrom() no major difference is known to me.

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?

Could be a simple coding mistake. Or somebody might have thought that recv'ing in tight loop would somehow increase the performance.


It is always better to make sockets as nonblocking because even a blocking socket becomes ready state sometimes (when data arrived but has checksum error and that is discarded) - even when there is no data to read. So make it nonblocking, wait for the data availability through poll then read. I think this is the main advantage.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜