2

有其他人在 10.6 中看到或听说过 NSTask 的任何问题吗?

该代码昨天运行良好,今天无法正常运行。

NSTask *task = [converter task];
[task waitUntilExit];
NSLog(@"Task did complete");

该任务完成了它应该做的事情(我检查了输出,它很好),但程序将无限期地等待该waitUntilExit方法。我有一些使用类似代码的单元测试,它们以前都通过了,但截至昨天,它们不再工作。

4

5 回答 5

2

您需要添加以下魔术线:

[task setStandardInput:[NSPipe pipe]];
于 2010-09-04T17:36:49.837 回答
1

(1) 你是否以任何方式处理任务的输出?如果是这样,如果您不沿途读取和处理数据,输出的缓冲可能会阻塞。

(2) 您的任务在终止之前是否在标准输入上等待 EOL?如果是这样,您将需要获取标准输入并明确关闭它。

正如彼得所说,检查 ps 以查看您的任务是否仍在运行。如果是,sample请对它进行采样以找出它在做什么。

于 2009-08-30T19:14:38.477 回答
1

可能 - 我注意到我在 10.6 上的一些代码有问题,这听起来很像你的问题。

我需要以完全异步的方式获取一些网络信息(主要是关于 BGP 和 AS 的东西)。对我来说理想的解决方案是将特殊的 DNS TXT 记录请求发送到可公开访问的 DNS 服务器,但 Cocoa/Core Foundation 不提供 API 来执行这些奇怪的 DNS 请求。另一种方法是使用shell% whois -h IP 'SPECIAL REQUEST'并从输出中解析出相关信息。这是我可以在几个小时内启动并运行的东西,然后再回来并提出一个真正的解决方案。非常 hacky,但比 1) 找到合适的异步 DNS 库和 2) 加快其 API 的速度并可能为其编写包装器要快得多。

因此,我创建了一个分叉后台线程的类,然后NSTask启动whois请求。后台线程位于一个NSRunLoop循环中以处理结果,但每隔约 1/10 秒检查一次以查看是否NSTask因某种原因死亡,或者 if[NSThread isCanceled]等。它还注册NSApplicationWillTerminateNotification通知,以便它可以进行适当的清理,如果应用程序正在退出。

好吧,从 10.6 开始……我不能再“快速”退出了。在 10.5 上,一切都是玻璃般光滑的,应用程序会立即退出,至少在感知上是这样。在 10.6 下,退出会导致应用“挂起”。调试表明一切都在试图清理挥之不去whois NSTask的 s。由于我以这种方式获得的所有信息都不是应用程序功能的关键(这是额外的,很高兴知道某种信息),我只是有点下注并停止尝试将信息作为权宜之计解决方案。

调试问题的快速通过表明主应用程序在尝试获取实例时被阻止NSLock。有趣的是,如果我不理会它,应用程序最终会正常退出——从 10-20 秒到几分钟不等。在 10.5 和 10.6 之间发生了一些变化,导致[NSLock lock] ... [NSLock unlock]块内的代码“花费很长时间”。不过,我还没有追查到发生这种情况的地方(还不是优先事项)....但是其中一件事是终止后台NSTask,如果它仍在运行并“等待它完成”,然后才能安全地摆脱它像它的东西NSPipe

DUP:这可能是一个骗人的答案……我的第一个似乎已经消失了?

于 2009-08-31T01:27:41.603 回答
0

检查 ps、top 或 Activity Monitor。确保您的进程已退出。

于 2009-08-30T16:25:42.623 回答
0

不确定这是否有帮助,但您可以尝试在单独的线程上等待:

[NSThread detachNewThreadSelector: @selector(foo) toTarget: self withObject: task];

...

- (void) foo: (NSTask *) task {
  [task launch];
  [task waitUntilExit];
  ...

我遇到了一个问题,任务完成后我没有收到 NSNotification,这解决了它。显然在 10.6 下的 NSTask 实现中存在一些错误......

于 2010-09-16T19:34:57.177 回答