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) タスクは終了する前に stdin で EOL を待ちますか? その場合は、stdin を取得して明示的に閉じます。

Peter が言ったように、ps をチェックして、タスクがまだ実行されているかどうかを確認してください。そうである場合は、 を使用sampleしてそれをサンプリングし、それが何をしているのかを把握します。

于 2009-08-30T19:14:38.477 に答える
1

おそらく-10.6 のコードの一部に、あなたの問題と疑わしいように聞こえる問題があることに気付きました。

完全に非同期でネットワーク情報 (主に BGP と AS に関するもの) を取得する必要がありました。私にとって理想的な解決策は、特別な DNS TXT レコード リクエストをパブリックにアクセス可能な DNS サーバーに送信することですが、Cocoa/Core Foundation は、この種の奇妙な DNS リクエストを行うための API を提供していません。別の方法はshell% whois -h IP 'SPECIAL REQUEST'、出力から関連情報を使用して解析することでした。これは、数時間で起動して実行し、後で戻って実際のソリューションを導入できるものでした. 非常にハックですが、1) 適切な非同期 DNS ライブラリを見つけること、および 2) その API を使いこなし、場合によってはそのラッパーを作成することよりもはるかに高速です。

そこで、バックグラウンド スレッドをフォークしNSTaskwhoisリクエストを開始するクラスを作成しました。バックグラウンド スレッドはNSRunLoop結果を処理するためにループにとどまりますが、1/10 秒ごとにチェックNSTaskして、何らかの理由で停止したかどうか、または[NSThread isCanceled]などを確認します。また、NSApplicationWillTerminateNotification通知を登録するため、アプリは終了しています。

さて、10.6 の時点で...「すぐに」終了できなくなりました。10.5 では、すべてが滑らかで、少なくとも知覚的にはアプリが即座に終了します。10.6 では、終了するとアプリが「ハング」します。whois NSTaskデバッグは、長引くsをクリーンアップしようとしてすべてがハングアップしていることを示しました。この方法で取得した情報はどれもアプリの機能にとって重要ではないため (余分な情報であり、そのような情報を知っておくと便利です)、一時的な解決策として情報を取得しようとするのをやめました。

問題をデバッグする際のクイック パスは、メイン アプリがインスタンスを取得しようとしてブロックされていることを示していましたNSLock。興味深いのは、そのままにしておくと、アプリケーションは最終的に正常に終了するということです.10〜20秒から数分.. 10.5と10.6の間で何かが変更され、[NSLock lock] ... [NSLock unlock]ブロック内に括弧で囲まれたコードが「時間がかかる」. 私はまだそれがどこで起こっているかを追跡する必要があります(まだ優先事項ではありません)....しかし、それらの1つは、バックグラウンドがNSTaskまだ実行されている場合はバックグラウンドを終了し、安全に取り除く前に「終了するのを待っています」。そのようなものNSPipe

DUP : これはだまされた答えかもしれません...私の最初の答えはどちらかに消えてしまったようです?

于 2009-08-31T01:27:41.603 に答える
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 に答える
0

ps、top、または Activity Monitor を確認します。プロセスが終了したことを確認してください。

于 2009-08-30T16:25:42.623 に答える