Five Reasons Why Synchronous Networking Is Bad
Five Reasons Why Synchronous Networking Is Bad
- Subject: Five Reasons Why Synchronous Networking Is Bad
- From: Quinn <email@hidden>
- Date: Thu, 5 Mar 2009 12:32:28 +0000
Greetings All
I wrote the following for an internal audience and various folks have
suggested that I post it externally. So here goes!
* * *
Five Reasons Why Synchronous Networking Is Bad
==============================================
When you do networking, you have a choice of three different modes:
o asynchronous -- For example, you can schedule an NSStream on a
runloop and have it call you when data arrives.
o synchronous, polled -- For example, you can periodically call
-[NSInputStream hasBytesAvailable] to see if data is available.
o synchronous, blocking -- For example, you can just call
-[NSInputStream read:maxLength:] which will block if no data is
available.
In virtually all cases I recommend that you use asynchronous
networking. That's because the other two options have fundamental
pitfalls, as explained by the rest of this document.
To start, it's obvious that polled mode is bad: it forces you to
choose between wasting CPU time or wasting network performance. If
you poll frequently then, on a slow network, you will be wasting CPU
time (and thus power, which is obviously an issue on mobile and
notebook hardware, but has recently become an issue on desktop and
server hardware as well). If you poll infrequently then, on a fast
network, you will be squandering network performance.
It's less obvious why synchronous blocking networking is bad. Each
of the five sections below describes a serious problem with it.
1. Resource Usage
-----------------
The number one reason synchronous blocking networking is bad is that
it wastes resources. You can't do synchronous blocking networking on
the main thread, so you necessarily have to create a secondary thread
to do the work. That thread is a waste of resources, most notably:
o virtual address space (always consumed)
o a /wired/ kernel stack (consumed while the thread is blocked)
This is especially bad when you're handling lots of connections
simultaneously, most of which are idle. You consume a bunch of wired
kernel stacks to get exactly /no/ work done.
2. Threads Are Evil
-------------------
Because synchronous blocking networking requires a secondary thread,
you have to deal with having multiple threads in your process. This
raises a host of thread-related issues, most notably the problem of
sharing data between threads. It's best to avoid this if you can.
3. Cancellation
---------------
Synchronous blocking networking makes it very hard to support
cancellation. You either have to jump through a bunch of hoops (see
my SocketCancel sample) or poll for cancellation (and did I mention
that polling was bad?).
<http://developer.apple.com/samplecode/SocketCancel/index.html>
4. Timeouts
-----------
Implementing a timeout is tricky with synchronous blocking
networking. Some synchronous blocking APIs implement some form of
timeout support, but not all. And where they do, the support tends
to be less robust than you'd like.
Again, you can work around this with various tricks but this serves
to further undermines the illusion that synchronous blocking
networking is easier.
5. Bidirectional
----------------
It's not possible to support full bidirectional communications on a
single synchronous blocking connection.
* * *
Share and Enjoy
--
Quinn "The Eskimo!" <http://www.apple.com/developer/>
Apple Developer Relations, Developer Technical Support, Core OS/Hardware
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Macnetworkprog mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden