11

いくつかのコールバック関数があり、複数のプロセスとして起動し、親プロセスからのシグナルを介してすべてを終了させたいと考えています。

これを行う私の現在の方法は、共有 c_bool を作成してmultiprocessing.Valueに設定しTrue、作成時にすべてのプロセスに配布することです。私のプロセスはすべて、次のように共有ブールを使用して while ループを実行します。

while myC_bool: ...keep running...

次に、bool を親プロセスから切り替えるだけでFalse、すべての子プロセスが最終ループを完了して終了します。

私は多くの人から言われ、マルチプロセッシングを使用するときは共有メモリを使用しないようにする必要があるとドキュメントを読みました。これを回避する最善の方法は、プロセスをデーモン化し、カスタム シグナル ハンドラを指定して、sigint/sigterm/etc を送信することだと言われました。

私の質問は、bool を排他的に使用してループを維持し、その値を親プロセスからのみ変更し、複数の子プロセスからそれを読み取って、すべての子プロセスを迅速かつ安全に終了させる適切なソリューションですか? x個の署名を送信するよりも、すべての子供が1つの共有ブールを見るだけのオーバーヘッドが少ないように感じます。

デーモン化はより良い解決策でしょうか? もしそうなら、私はその理由を理解する助けが欲しい.

4

3 に答える 3

14

ソリューションを使用する正当な理由はたくさんあります。

  • 信号よりも考えやすいです。
  • 対処するクロスプラットフォームの問題が少なくなります。
  • この方法で動作するコードは既にあります。
  • 将来必要に応じて、「グレースフル シャットダウン」メカニズムを簡単に追加できます。

… 等々。

multiprocessing関心のあるすべてのプラットフォームで、基盤となる OS プリミティブがここで同期なしで動作することが保証されていることを自分自身で証明できない限りLock、共有 bool へのすべてのアクセスの周りに a または何かを配置する必要があることに注意してください。それは厳密には複雑ではありませんが、一度それを行うと、たとえば、Event共有 bool を使用せずに an を使用する方がさらに簡単になる可能性があります。

いずれにせよ、それらのいずれかがあなたの理由である場合、私は素晴らしいと思います、そのようにしてください. しかし、あなたの質問によると、実際にはパフォーマンスのためにこれを選択しました:

x個の署名を送信するよりも、すべての子供が1つの共有ブールを見るだけのオーバーヘッドが少ないように感じます

それがあなたの理由なら、あなたはほぼ間違いなく間違っています。子は、何らかのループを介して毎回共有ブール値を確認 (および共有ロックを取得) する必要がありますが、シグナルは各子に一度だけ送信する必要があります。したがって、オーバーヘッドはほぼ確実にこの方法ではるかに高くなります。

しかし、実際には、子プロセスごとに 1 つのシグナルを送信したり、プロセスごとのループごとに 1 回プロセス間ロックを取得したりするオーバーヘッドが、有用なプログラムのボトルネックに近いとは想像もできません。そもそも?最もシンプルな方法で最も意味のあることを行います。

于 2013-04-02T00:13:25.320 に答える
2

誰が共有変数を変更するかについて注意しているので、問題ないはずです。

さまざまな解決策が考えられます。たとえば、 a を使用しmultiprocessing.Event、設定時にプロセスを終了させます。またはmultiprocessing.Connection(パイプから)オブジェクトを使用します。後者は、親と子の間の双方向通信に使用できます。子供たちへの停止の合図の後に、親への確認が続きます。

于 2013-04-01T22:10:33.847 に答える