re: User-space threads and NSAutoreleasePool
re: User-space threads and NSAutoreleasePool
- Subject: re: User-space threads and NSAutoreleasePool
- From: Ben Trumbull <email@hidden>
- Date: Thu, 18 Mar 2010 14:12:48 -0700
> 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@hidden)
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:
This email sent to email@hidden