简体   繁体   中英

Linux Networking IO Noob: Select() and Recvfrom, Blocking or Non-blocking?

I inherited a piece of code that reads in data from a UDP socket. I need some help figuring out what's going on here and also if I can improve anything performance wide.

The code starts by calling select(), and then recvfrom(). Based on my research, it appears that recvfrom() is only called when select() returns the fact that there is data available. This code basically consists of a thread that continuously listens for a multicast message. As a result, it basically sits in the select() routine until it either receives data or times out.

I was wondering if there was perhaps a better way to improve upon the performance of this code. First, is select() necessary? Based on this thread: setting timeout for recv fcn of a UDP socket it appears that I can just set the timeout of the recvfrom() command itself. Will this buy me anything? Also, based on some research, I've seen alot of implementations without select(). Why is this?

Also, ideally, I'd like to free up as much CPU as possible. Is there a way that I can put the process to sleep until it receives a packet? That being said, I'd like to receive a full packet at a time for simplicity sake.

Thanks in advance for the help.

When recvfrom blocks or when select is waiting for an event, the process is effectively asleep; that is, it is not scheduled to run. So your existing code (at least if I'm interpreting your description correctly) already satisfies your first requirement.

Is there a way that I can put the process to sleep until it receives a packet?

UDP is a "datagram packet service". (Quoted from man 7 udp ). That is, it always sends and receives complete packets. So with UDP, you never have to worry about your second requirement:

I'd like to receive a full packet at a time for simplicity sake.

All in all, I'd say you don't have a problem.

However, you may be able to remove the select() call, if it is only waiting on a single descriptor, assuming you are able to setsocketopt() SO_RCVTIMEO (which you probably can do, although Posix allows an individual implementation to not allow the option to be set, so there is no absolute guarantee.) I doubt whether you will notice any performance improvement from doing so, but it should save a few microseconds.

Is there a way that I can put the process to sleep until it receives a packet?

You're already doing that. That's what select() does, or recvfrom() in blocking mode.

I'd like to receive a full packet at a time for simplicity sake.

That's what UDP is already doing for you.

可能会有所帮助: 10k问题

I can just set the timeout of the recvfrom() command itself

If select waits on only one file descriptor (eg socket), then there would be not much difference with what you propose. But if this manages more than one, then there isn't really a better solution to this.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM