问题描述
我有一个多线程程序,需要一次运行许多可执行文件,并等待他们的结果。
我在中使用
在非主线程上运行它(在主线程上运行 [nstask waitUntilExit]
NSOperationQueue NSTask
)是完全没有问题的。)
我的程序随机崩溃或运行到断言失败,并且崩溃堆栈总是指向由 waitUntilExit
运行的runloop运行,它执行各种回调和处理程序,包括-IMHO不正确 - KVO和,这导致它们在非主线程上运行()
如何安全地使用 waitUntilExit
?
这是 waitUntilExit
的问题本质上是不可用的,或者我需要做一些特别的事情使用KVO和IB绑定来防止它们在错误的线程上处理 waitUntilExit
?
但是,你可以使用 terminationHandler
在10.7+。它不泵浦runloop,所以不应该创建这个问题。您可以沿着这些行重新创建 waitUntilExit
(未测试;可能无法编译):
dispatch_group group = dispatch_group_create();
dispatch_group_enter(group);
task.terminationHandler = ^ {dispatch_group_leave(group); };
[任务启动];
dispatch_group_wait(group,DISPATCH_TIME_FOREVER);
I have a multithreaded program that needs to run many executables at once and wait for their results.
I use [nstask waitUntilExit]
in an NSOperationQueue
that runs it on non-main thread (running NSTask
on the main thread is completely out of the question).
My program randomly crashes or runs into assertion failures, and the crash stacks always point to the runloop run by waitUntilExit
, which executes various callbacks and handlers, including—IMHO incorrectly—KVO and bindings updating the UI, which causes them to run on non-main thread (It's probably the problem described by Mike Ash)
How can I safely use waitUntilExit
?
Is it a problem of waitUntilExit
being essentially unusable, or do I need to do something special (apart from explicitly scheduling my callbacks on the main thread) when using KVO and IB bindings to prevent them from being handled on a wrong thread running waitUntilExit
?
As Mike Ash points out, you just can't call waitUntilExit
on a random runloop. It's convenient, but it doesn't work. You have to include "doesn't work" in your computation of "is this actually convenient?"
You can, however, use terminationHandler
in 10.7+. It does not pump the runloop, so shouldn't create this problem. You can recreate waitUntilExit
with something along these lines (untested; probably doesn't compile):
dispatch_group group = dispatch_group_create();
dispatch_group_enter(group);
task.terminationHandler = ^{ dispatch_group_leave(group); };
[task launch];
dispatch_group_wait(group, DISPATCH_TIME_FOREVER);
这篇关于如何安全使用[NSTask waitUntilExit]关闭主线程?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!