Question

Yesterday I read somewhere that NSTask isn't thread safe and that bothers me a lot, because I'm running a NSTask within a NSThread and is so far not experiencing any threading issues with it.

My code is organized like this

A: main thread -> B: worker thread -> C: worker task

C: The worker task is a commandline program.
B: The worker thread can start/stop the worker task and send it commands.
A: The main thread can send commands to the worker thread.

If NSTask is supposed to be used only within the main thread, then I'm considering moving the NSTask start/stop code to the main thread, just to prevent possible threading issues.

Can NSTask be used outside the main thread?

And if not then what may be the threading issues with NSTask?

Was it helpful?

Solution

I read somewhere that NSTask isn't thread safe

That's not what that page says. It says that you'll get the process-terminated notification on the same thread you launched it from, which suggests that NSTask is aware of threads and tries to do the right thing.

The problem one of the editors of that page encountered was that they started their process from a thread, then let the thread die. That caused a crash because the framework was no longer able to deliver the process-terminated notification to the correct thread.

The Thread Safety Summary (bookmark that) says something similar, listing NSTask in a list of classes about which it says:

In most cases, you can use these classes from any thread as long as you use them from only one thread at a time. Check the class documentation for additional details.

The NSTask documentation doesn't say anything additional about threads, so it sounds like NSTask is one of the “most cases”: You can use a task from the thread you created it on. Don't use the same task on another thread, and (as noted above) make sure the thread lasts at least as long as the task process.

I will note, however, that in most cases, there is no need to run a task on a separate thread. Separate processes tend to run on other processors just as other threads in your process do, and the run loop does a good job of multiplexing many small events and keeping the UI responsive. You can use NSFileHandle's readInBackgroundAndNotify method if you need to read output from the task. You may be able to cut out your worker threads entirely.

The alternative is, as Eimantas suggested, to use NSOperation: Have an operation that simply starts a particular task and waits for that task to exit (perhaps synchronously reading output from it). The operation is complete when the task has exited.

OTHER TIPS

Yes, it can, but I suggest you using NSOperation. It's KVO-agnostic (unlike threaded NSTask). Also you may want to look into receptionist design pattern regarding KVO and threaded environment (in case you need KVO).

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top