Re: Waking up a network server: 2 threads + semaphore vs 1 thread + pipe
Re: Waking up a network server: 2 threads + semaphore vs 1 thread + pipe
- Subject: Re: Waking up a network server: 2 threads + semaphore vs 1 thread + pipe
- From: "A.M." <email@hidden>
- Date: Tue, 17 Feb 2009 12:02:57 -0500
On Feb 14, 2009, at 9:54 AM, Joel Reymont wrote:
Terry,
On Feb 14, 2009, at 2:19 PM, Terry Lambert wrote:
Please do not crosspost, especially to subscription-required-to-
reply lists.
My apologies. Certain experts are not on every list... like you.
You've actually said almost nothing about your problem space, other
than implying that the packets are network MTU sized or smaller by
discounting UDP vs. TCP and therefore packet reassembly after
fragmentation doesn't come into play..
I tried to give just enough background to make it suitable for the
lists I was posting to.
The problem space is real-time audio generation on the iPhone (VoIP
or synthesized music) and the broadcast of said audio. The
application is supposed to send, receive, mix microphone with
generated audio and do it without stuttering. Imagine that the
iPhone is an instrument and you are trying to put together a
distributed orchestra.
CoreAudio triggers a callback every few milliseconds to both ask for
audio and to supply it. I'm using ring buffers to store generated
audio and packets received from the network.
I will need to invoke sendto (or CFSocketSendData) in a loop to
deliver audio to clients but I don't think it's proper to do it from
within the CoreAudio callback.
I can wrap CFSockets around my native sockets and add them to the
run loop but it seems from reading the source code that CFSocket may
run a thread per socket. The "you can read" notification will be
handled then and I'll just need to run a thread to iterate through
my sockets and send the audio. I figure can wake up this thread from
the CoreAudio callback by using a semaphore.
Alternatively, I can track my sockets with select or kevent/kqueue
and use the same mechanism to track a pipe and wake the sending
thread. This will only require one thread since it will be woken up
on both sends (byte put into a pipe) and receives.
Which is the best design and how efficient?
How efficient is it to put a byte into a pipe in a callback that
gets triggered every few milliseconds? Would there be a significant
gain since an extra thread is not required to wait on a semaphore?
Would it even out since (intuitively) a pipe is slower?
Thanks, Joel
Take a look the CFSocketManager code surrounding the CFRunLoop:
http://google.com/codesearch/p?hl=en#Uhw2V3njhPU/Current/CF-368.25/
RunLoop.subproj/CFSocket.c&q=CFSocketManager
There is one thread (CFSocketManager thread) for all CFSockets.
The problem you will hit is that NSRunLoop will starve user event
processing (including app drawing) while processing lots of socket
data. It's not sufficient to offload the data receipt notifications
from the main runloop, you should also offload the packet processing
and then only update the program state from the secondary thread.
The ultimate design of you application will depend on how much data
needs to be processed and how many sockets you expect to be connected
at any time. If I were you, I would start off with a simple secondary
thread and NSRunLoop and use CFSockets hanging off of that and
optimize later based on what profiling tells you.
Cheers,
M
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Darwin-dev mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden