> The problem is that when you call swapcontext() to switch the user-thread
> running on a kernel-thread, the NSAutoreleasePool stack is not swapped out.
> It remains rooted in thread-local storage. As a result, serious problems
> result. Let me give an example.
>
> - (void)doStuff {
> NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
> // do some stuff that calls swapcontext()
> [pool drain];
> }
That doesn't work correctly with regular threads, pthreads, GCD or any other
concurrency pattern. The autorelease pool needs to be pushed and popped within
the context of the asynchronous subtask. The original thread of control needs
its own pool, and you cannot rely upon autorelease to keep objects alive across
asynchronous task boundaries. You will need to be careful to ensure that the
sending thread transfers ownership of a retain to the receiving thread which
releases it. Not autoreleases it.
It would need to conceptually be:
- (void)doStuff {
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
// some stuff Before
[pool drain];
// do some stuff that calls swapcontext(), and has it's only scoped
autorelease pool
pool = [[NSAutoreleasePool alloc] init];
// some more stuff After
[pool drain];
}
Object you want to keep alive across drains should be retained and later
released.
Autorelease pools are cheap. Make more. A lot more. If you have places where
that doesn't work with coroutines then don't leak important objects into
autorelease pools. Either don't create them that way, or retain them again,
and release them after you can verify the autorelease pool was destroyed.
> Using kernel-level
> threads is, naturally, simpler, but due to the cost of kernel-level context
> switches, they don't scale well. (You just can't run 500 threads at once
> very well.) User-space threads require more programmer attention, certainly,
> but also allow certain programming models that can't be done otherwise. For
> example, they can be used for coroutines, cooperative threading, or all
> sorts of esoteric-yet-sometimes-useful effects.
That's true, but I'm not sure it's relevant for the "I wish I had 500 threads
to handle this web server communication" task. There are a lot of different
ways to organize the tasks as inert data that can be processed cooperatively by
a set of active worker threads.
The mental model of each task being its own little world and a thread is nice,
but it's also artificial. You can reorganize the relationship between active
workers and command data. Nothing is stopping you from that except a
preconception that tasks and threads must have a 1:1 correspondence.
You could create a finite state machine to process a queue of the tasks as
inert command structures and firing up 8 of those finite state machines on
their own dedicated normal threads on your Mac Pro. The semantic effect will
be similar to user threads, yet you won't run into all these crazy problems.
Destroying thread local storage and its affect on autorelease pools is just
your first problem stuffing Cocoa into swapcontext()
This point from Mike is particularly apt:
> Since you mention in another message that this is portable,
> cross-platform code, why do you need to call Cocoa from the user-level
> threads at all? Separate your code into cross-platform code that does
> this swapcontext stuff, and Mac-specific code that doesn't, and you
> should be good.
You could use a sandboxing approach like Safari and have your cross platform
code run in a background CLI and talk to the GUI app over IPC. No Cocoa in the
CLI and no user threads in the GUI app.
Pretty sure, though, you'd get better performance conceptually restructuring
the task / actor relationship. The cooperative finite state machine approach
along with a prioritized queue can provide soft real time performance with
thousands of task objects ... every second. That's basically what some older
MMORPG servers did before people went wild with distributed computing.
- Ben
_______________________________________________
Cocoa-dev mailing list ([email protected])
Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com
This email sent to [email protected]