0

昨日、NSThread内でNSTaskを実行していて、これまでのところスレッドの問題が発生していないため、NSTaskはスレッドセーフではなく、非常に煩わしいとどこかで読みました。

私のコードはこのように構成されています

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.

NSTaskがメインスレッド内でのみ使用されることになっている場合は、スレッドの問題を防ぐために、NSTaskの開始/停止コードをメインスレッドに移動することを検討しています。

NSTaskはメインスレッドの外で使用できますか?

そうでない場合は、NSTaskのスレッドの問題は何でしょうか?

4

2 に答える 2

4

NSTaskはスレッドセーフではないことをどこかで読みました… </p>

それはそのページが言っていることではありません。これは、起動したのと同じスレッドでプロセス終了通知を受け取ることを示しています。これは、NSTaskがスレッドを認識しており、正しいことを行おうとしていることを示しています。

そのページの編集者の1人が遭遇した問題は、スレッドからプロセスを開始してから、スレッドを終了させることでした。フレームワークがプロセス終了通知を正しいスレッドに配信できなくなったため、クラッシュが発生しました。

スレッドセーフサマリー(ブックマーク)は似たようなことを言っており、NSTaskをそれが言っているクラスのリストにリストしています:

ほとんどの場合、一度に1つのスレッドからのみ使用する限り、これらのクラスは任意のスレッドから使​​用できます。詳細については、クラスのドキュメントを確認してください。

NSTaskのドキュメントにはスレッドに関する追加の記述がないため、NSTaskは「ほとんどの場合」の1つであるように思われます。作成したスレッドからタスクを使用できます。別のスレッドで同じタスクを使用しないでください。また、(上記のように)スレッドが少なくともタスクプロセスと同じくらい長く続くことを確認してください。

ただし、ほとんどの場合、別のスレッドでタスクを実行する必要はありません。個別のプロセスは、プロセス内の他のスレッドと同じように他のプロセッサで実行される傾向があり、実行ループは、多くの小さなイベントを多重化し、UIの応答性を維持するのに適しています。タスクからの出力を読み取る必要がある場合は、NSFileHandleのreadInBackgroundAndNotifyメソッドを使用できます。ワーカースレッドを完全に切り取ることができる場合があります。

別の方法は、Eimantasが提案したように、NSOperationを使用することです。特定のタスクを開始し、そのタスクが終了するのを待つ(おそらく同期的に出力を読み取る)操作を行います。タスクが終了すると、操作は完了します。

于 2010-06-13T00:50:47.303 に答える
0

はい、できますが、を使用することをお勧めしますNSOperation。これはKVOに依存しません(スレッド化とは異なりNSTaskます)。また、KVOとスレッド環境(KVOが必要な場合)に関する受付のデザインパターンを調べることもできます。

于 2010-06-12T20:01:46.913 に答える