web-dev-qa-db-ja.com

再帰的フォークはアンチパターンと見なされますか?

プロセスフォークをいじくり始めました。子プロセスに作業が分散され、結果が親プロセスに返される例を書こうと思いました。このようにして、複数のプロセッサで並行して実行できます。

私の最初の試みでは、ループでフォークしています。つまり、毎回、既存のすべてのプロセス(元のプロセス、子、孫など)が別のフォークを生成します。

これは私に問題(メモリ消費、プロセス数の急激な増加、データをチェーンに戻すためのパイプの追跡など)を引き起こしており、アンチパターンに遭遇したのではないかと思います。 I could N人の子を親から直接フォークするだけです。

Forkとexecが複数回行われることはよくあることだと思います。たとえば、ターミナルはシェルをフォークし、シェルはエディターをフォークします。しかし子供たちがすべて同じタイプであるときに「再帰的に」フォークすることは悪い習慣と見なされますか?

6
Nathan Long

制御されていないフォークは間違いなくアンチパターンです。ご存知のように、利用可能なすべてのリソースを消費するのは比較的簡単で、その後、すべてが完全に停止するまでそれらを消費し続けます。

魔術師の見習い に聞いてください。

再帰に関連する他の問題と同様に、終了条件を明確に理解する必要があります。アルゴリズムが終了しない可能性がある場合、スタックの深さを制御できないため、再帰は完全に不適切です。

もちろん、一部のタスクは他のタスクを「発見」する可能性があるため、親プロセスからすべてを直接起動することは不可能な場合もあります。

ソリューションを簡略化するためによく使用される戦略の1つは、ある種のタスクマネージャプロセスを作成し、保留中のタスクのキューを消費させることです。マスタータスクまたは子は、タスクを見つけたときにキューに追加できます。タスクマネージャは、タスクを処理するために必要な数のプロセスをフォークします。

このようにして、タスクマネージャーは実行中のプロセスの総数をカウントし、必要であるとハードウェアが対応できる場合にのみ新しいプロセスをforkできます。

もちろん、これでブロックするリスクがあります。一部のタスクは、続行する前に別のタスクの結果を必要としますが、他のタスクはキューにあり、現在実行中のすべてのタスクがブロックしているため、実行されません。まだ開始されていません...

これを修正するには、結果を消費することをジョブとする個別のタスクを用意し、それらを個別のタスクマネージャーで管理します。そうすれば、計算が完全にブロックされることはありません。何かが常に進行します。

7
Bill Michell

複数のプロセスを分散させたい場合の目標は、処理時間を最小限に抑えることです。何を最小化するかを定義する必要があります。通常、これは最近傍または幾何関数または2次元関数f(x)= yです。再帰はそのような関数ではありませんが、たとえば関数f(x)= yをトラバースするためにグレイコードを調べることができます。左ビットと右ビットを区別するのに役立ちます。

0
Gigamegs