View Full Version : Why FD_WRITE is usefull on select()?

06-30-2010, 09:50 AM
Hi guys,

I've played with select() and FD_READ/FD_ACCEPT and since I got it working right, it's more than 6 months I haven't looked at it.

Now I'm wondering why one would use FD_WRITE? I just can't see the advantage of waiting to get triggerd for writing.

I hope someone can come up with a good scenario where FD_WRITE with select would be very usefull.

Thank you.

06-30-2010, 10:10 AM
It has to do with SLOW connections. if you are, for example, on a RS232 at 9600bps, with a 64 byte write buffer on the device, you want to know when you can write again so that you can continue on with your normal life.

06-30-2010, 10:22 AM
It's not just slow connections, really. The whole point of efficient IO is to not block when you could be doing other processing. The OS will queue a certain amount of data for you, but you don't know how much, so a call to send() may take an unpredictably long time to complete. You only want to call recv() and send() when something can actually happen.

Multiplexing servers typically keep a structure or class to represent both the incoming and outgoing traffic on a socket. When the server wants to write data to the connection, it doesn't do so directly with send(), it just sticks it on the outgoing queue. Similarly, when it wants to read it loads data from the incoming queue instead of calling recv() directly.

In the meantime the server's main loop is calling select(), then processing each file descriptor for input and output -- if input is available, it sticks it on the incoming queue for that connection. If the fd is available for writing, it sends as much data from the outgoing queue as it can, without blocking.

06-30-2010, 11:14 AM
True, I guess a better word to use would have been BUSY -- implying that the connection is "overworked" for the moment and a write would not succeed promptly.

Technically, I guess, one could even use select() on a database back-end that access a busy disk.

Now that I'm thinking about it -- there are hundreds of uses for a select on write.

07-01-2010, 02:23 AM
Thank you for your vaulable posts,

Ok, so if I understand it well, it's for making it non-blocking.

This means that after select() returns for a write, you have to check which fd can send and than get the message to be sent from a queue belonging to that fd.

But we have to do some precautions, cause when sending, it's not guaranteed that all data are sent, so the remaining bytes should be sent also when a next write-session is triggered. When everything is sent, you can remove that message from that queue and get next message from the queue.

That's the kind of concept I can think of, I bet there are more intelligent solutions or more flexible solutions...

But am I on the right track?

07-01-2010, 09:44 AM
What platform are you on because there's no FD_WRITE select macro on any of the *nixes.

07-01-2010, 09:56 AM
You are right, there is no FD_WRITE macro, but I mean the writeset in the select() argument. I use Linux.

07-01-2010, 10:02 AM
I could also ommit messages in the queue and just get a buffer of size 1024 bytes for example and append the messages in the buffer. I think this is a bit easier and simpler than adding each message as a separate buffer in a list.

What do you think? I hope you guys understand what I mean.