複数のバックグラウンドジョブのデータをBashの単一のデータストリームに再結合する方法

複数のバックグラウンドジョブのデータをBashの単一のデータストリームに再結合する方法

シングルコアバウンドジョブを複数の部分に分割し、各部分をbashで別々のタスクとして実行して並列化できる同様の状況に直面しましたが、返されたデータを単一のデータに変換するのに問題があります。小川。これまでの私の素朴なアプローチは、一時フォルダを作成し、PIDを追跡し、各スレッドにそのPIDをファイルに書き込むようにし、すべての作業が完了したら、すべてのPIDを読み取り、順番にマージすることです。 PIDがファイルとして生成されました。これらの複数入力と単一出力の状況を処理するためにbash /シェルツールを使用するより良い方法はありますか?

答え1

これまでの私の素朴なアプローチは、一時フォルダを作成し、PIDを追跡し、各スレッドにそのPIDをファイルに書き込むようにし、すべての作業が完了したら、すべてのPIDを読み取り、順番にマージすることです。 PIDがファイルとして生成されました。

これはGNU Parallelが行うこととほぼ同じです。

parallel do_stuff ::: job1 job2 job3 ... jobn > output

いくつかの追加の利点があります。

  • 一時ファイルは自動的に削除されるため、GNU Parallelを終了してもクリーンアップは必要ありません。
  • 現在実行中のジョブに一時スペースを提供するだけです。完了したジョブの一時スペースは、ジョブの完了後に解放されます。
  • 出力が入力と同じ順序で行われるようにするには、を使用します--keep-order
  • 他のジョブの1行ずつ混合出力が必要な場合を使用します--line-buffer

GNU Parallelには、タスクをより小さなタスクに分割する多くの機能があります。たぶん、これらのうちの1つを使って小さな仕事を作ることができますか?

答え2

あなたの提案は、完了する前にデータをマージする方法について考えていないので、非常に合理的なようです。だから正直言って、それは悪いアプローチではありません!

別の一般的な解決策は、データを収集し、データ「スライス」の意味/境界を理解し、いつでもコンテンツをマージする中央プログラムを保持することです。

これを行う方法は、生成するデータの種類によって大きく異なります。これは、UNIX、UDP、またはTCPソケットからメッセージを読み取る最小限のプログラムと同じくらい簡単です。 。または、小規模リレーショナルデータベースサーバー(PostgreSQL?)を実行してください。あるいは、ØMQソケットを使用して複数のサイト運営者を保持し、中央でこれらのサイト運営者の購読者にマージすることができます。これはネットワークを介してすぐに機能するという利点もあります。または、データベースを使用して時系列データを保存します。あるいは、データはログメッセージのように見えるため、syslogまたはsyslogを介して結果を記録するワーカーを実装し、sd_journal_printJournaldのジャーナル名前空間を使用してすべてのログメッセージを単一のファイルに保存します。または...

結局のところ、あなたのオプションは次のとおりです。

  1. 多くのファイルに書き込んで後でマージします(ここでは以下を使用しています)。ファイルシステム問題なく他のワーカーが他のファイルへの同時書き込みアクセスを許可します。
  2. 一種のパイプ/ソケット/プロセス間通信方式を使用して中央プロセスにメッセージを送信します。ここでは、データ構造を知っていてすぐにマージを実行できるという事実を使用します。

実際にこれを行う方法は、データ構造、ボリューム、およびマージ方法によって100%異なります。

関連情報