Cocoa OS X 10.6 Snow Leopard中的NSTask问题

Cocoa OS X 10.6 Snow Leopard中的NSTask问题,cocoa,macos,osx-snow-leopard,nstask,Cocoa,Macos,Osx Snow Leopard,Nstask,是否有其他人看到或听说过10.6中NSTask的任何问题 该代码昨天运行良好,但今天不起作用 NSTask *task = [converter task]; [task waitUntilExit]; NSLog(@"Task did complete"); 任务执行它应该执行的操作(我检查了输出,结果很好),但是程序将在waitUntilExit方法中无限期地等待。我有一些使用类似代码的单元测试,它们以前都通过了,但到昨天为止,它们不再工作。检查ps、top或Activity Monito

是否有其他人看到或听说过10.6中NSTask的任何问题

该代码昨天运行良好,但今天不起作用

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

任务执行它应该执行的操作(我检查了输出,结果很好),但是程序将在
waitUntilExit
方法中无限期地等待。我有一些使用类似代码的单元测试,它们以前都通过了,但到昨天为止,它们不再工作。

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

(1)您是否以任何方式处理任务的输出?如果是这样的话,如果您不在过程中读取和处理数据,那么输出的缓冲可能会阻塞

(2) 您的任务是否在终止之前等待stdin上的EOL?如果是这样,您将需要获取stdin并显式关闭它


正如Peter所说,检查ps以查看您的任务是否仍在运行。如果是,请使用
sample
对其进行采样,以了解其用途。

可能-我注意到我在10.6上的一些代码出现了一个问题,听起来很像您的问题

我需要以完全异步的方式获取一些网络信息(主要是关于BGP和AS的信息)。ME的理想解决方案是向公共可访问DNS服务器发送特殊DNS TXT记录请求,但是COCOA/Core基金会不提供用于执行这些类型的奇数球DNS请求的API。另一种方法是使用
shell%whois-hip“特殊请求”
并从输出中解析出相关信息。这是我可以在几个小时内启动并运行的东西,稍后再回来并提出真正的解决方案。非常有黑客味,但比1)找到合适的异步DNS库和2)加快其API速度并可能为其编写包装器要快得多

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

那么从10.6开始。。。我再也不能“快速”退出了。在10.5上,一切都是玻璃般光滑的,应用程序会立即退出,至少在感知上是这样。根据10.6,退出会导致应用程序“挂起”。调试表明,在试图清理挥之不去的
whoisntask
s时,一切都挂断了。由于我通过这种方式获得的信息对应用程序的功能都不重要(这是一种额外的、很高兴知道的信息),所以我只是有点犹豫,不再试图获取这些信息作为权宜之计

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


DUP:这可能是一个重复的答案。。。我的第一条似乎已消失在“要么?”中。

您需要添加以下魔线:

[task setStandardInput:[NSPipe pipe]];

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

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

...

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

我遇到了一个问题,任务完成时我没有收到通知,这就解决了这个问题。显然,10.6下的NSTask实现中存在一些bug…

它显示在Activity Monitor中并正常退出。正在转换的文件已转换且未损坏。看起来任务正在完成,但不知何故没有通知任何人任务已经完成。这听起来很像我的问题。我没有接触NSLock,新进程完全通过NSTask控制,所以我的问题就在那里。糟糕的是,你还没有解决方案,但如果我发现了什么,我会让你保持更新。如果你替换一个简单的脚本,只拉一个出口0;对于您现在正在使用的代码,我看到了一个类似的问题,上面的代码有时会立即完成,有时需要几秒钟或更长时间才能完成。真奇怪!