asynchronous socket writing
minfrin at sharp.fm
Thu Mar 11 12:06:30 CET 2010
On 10 Mar 2010, at 8:15 PM, Jonas H. wrote:
> I'm currently taking my first steps in socket/C programming and I
> want to implement a fast, multi-threaded web server for testing
> purpose. I decided to have a single accept/listen/whatever thread
> for now. However, I want asynchronous read at write (at least write).
> So the question is: How do I implemented asynchronous I/O?
> (Maybe this isn't /too/ libev specific but more a general question.)
> If I get things right, the UNIX `read`/`recv` and `write`/`send`
> aren't non-blocking/asynchronous. Putting the write stuff into an
> own thread does not change anything. Did I get something wrong?
> I'm grateful for any tips. Thanks! :-)
I would suggest start by leaving the threads out, and get asynchronous
io working in a single thread. Once you're comfortable with that, then
try and look at your code from a threaded angle. (I am assuming you
are experimenting at this stage).
The key thing about async io that you'll never block, and that means
you need to react appropriately to EAGAIN and EWOULDBLOCK.
The event library will take you extremely literally, if you've asked
to be notified when the socket is ready to be written to, the event
library will keep notifying you the socket is ready to be written to,
over and over in a tight loop until such time as the socket is no
longer ready to b written to, and this is normal.
What you need to do is use the start and stop functions in the event
api to turn on the write event when you are ready to write something,
and to stop the write event when you no longer have anything to write.
The same goes for the read event. If a socket becomes readable, but
you're not ready to read the data just yet for whatever reason (you're
busy waiting for something else to happen first, for example), that
event too will spin telling you over and over that something is
readable, again giving you a spin. Again, you need to control the
event with a start and stop, as appropriate.
The general rule while developing this stuff is to make sure you look
for spins while you are developing. Your code may appear to work fine,
but chew 100% of a CPU because an event is started when it should be
stopped, and this needs to be watched for.
More information about the libev