堅牢でスケーラブルである必要がある Linux 専用の syslog 処理デーモンを設計しており、マルチスレッドとマルチプロセスについて議論しています。
マルチスレッドの明らかな反対は、複雑さと厄介なバグです。マルチプロセスは、IPC 通信とコンテキスト切り替えのためにパフォーマンスに影響を与える可能性があります。
「Unix プログラミングの芸術」では、これについてここで説明しています。
プロセスベースのシステム (Apache など) とマルチスレッドのアプローチのどちらをお勧めしますか?
堅牢でスケーラブルである必要がある Linux 専用の syslog 処理デーモンを設計しており、マルチスレッドとマルチプロセスについて議論しています。
マルチスレッドの明らかな反対は、複雑さと厄介なバグです。マルチプロセスは、IPC 通信とコンテキスト切り替えのためにパフォーマンスに影響を与える可能性があります。
「Unix プログラミングの芸術」では、これについてここで説明しています。
プロセスベースのシステム (Apache など) とマルチスレッドのアプローチのどちらをお勧めしますか?
どちらも、独自の方法で複雑で複雑になる可能性があります。
どちらでも構いません。物事の壮大な計画では、どちらを選択してもかまわないかもしれません。重要なのは、それらをどれだけうまく行うかです。したがって:
あなたが最も経験したことをしてください。または、チームを率いる場合は、チームが最も経験を積んでいることを行います。
---スレッディング!---
私は多くのスレッド化プログラミングを行ってきましたが、楽しんでいる部分とそうでない部分があります。私は多くのことを学び、今ではたいてい苦労せずにマルチスレッド アプリケーションを作成できますが、非常に特殊な方法で作成する必要があります。すなわち:
1) 100% スレッド セーフな非常に明確に定義されたデータ境界で記述される必要があります。そうしないと、発生する可能性のある状況が発生する可能性があり、デバッガーが配置されている場合は発生しない可能性があります.さらに、スレッド化されたコードのデバッグは、シュレディンガーの箱を覗き込むようなものです...そこを見ると、他のスレッドがもっと処理する時間がありました。
2) マシンに負荷をかけるテスト コードを記述する必要があります。多くのマルチスレッド システムでは、マシンに大きな負荷がかかっている場合にのみバグが発生します。
3) データ交換コードを所有している非常に賢い人がいるに違いありません。ショートカットを作成する方法があれば、開発者が作成する可能性があり、誤ったバグが発生する可能性があります。
4) 最小限の手間でアプリケーションをリセットする包括的な状況が必要です。これは、スレッドの問題が原因で壊れた製品コード用です。要するに、ショーは続けなければなりません。
- -クロスプロセス! - -
私はプロセスベースのスレッド化の経験はあまりありませんが、最近 Windows でいくつかのクロスプロセス処理を行っています (ここで、IPC は Web サービスの呼び出しです... うわー!)、比較的クリーンでシンプルですが、いくつかの規則に従います。ここでも。プログラムは外部からの入力を非常にうまく受け取るため、概して、プロセス間通信ははるかにエラーのないものになります..そして、それらのトランスポートメカニズムは通常非同期です。ともかく...
1) 明確なプロセス境界と通信メカニズムを定義します。国境が明確で、それらの境界に多くの検証およびエラーチェックコードがある限り、TCP、Web サービス、またはパイプなどを介したメッセージ/イベント処理は問題ありません。
2) ボトルネックに備える。コードの寛容性は非常に重要です。つまり、そのパイプに書き込めない場合があります。アプリケーションがロックアップしたり例外を投げたりすることなく、これらのメッセージを再キューイングして再試行できる必要があります。
3) プロセスの境界を越えてデータを転送するということは、何らかの方法でシリアル化する必要があることを意味するため、一般的にはより多くのコードが存在します。これは、特にそのコードの保守と変更を開始するときに、問題の原因になる可能性があります。
お役に立てれば。
詳細を省略しすぎています。実際、あなたがすでに述べたことに関して、選択は無関係であり、マルチプロセッシングほどマルチスレッドについて本質的にバグのあるものはありません。なぜこれらの手法がそのような評判を得ているのかを見逃しています。データを共有していない場合は、大きな問題はありません (もちろん、他にも問題がある可能性がありますが、それらについて判断するには詳細が必要です)。また、UNIX のようなオペレーティング システムでは、どのプラットフォームでもプロセスが非常に軽量であることも重要です。
しかし、考慮すべき他の問題はありますか?どのようなシステムで実行しますか? 指定できる他の詳細によっては、あまりメリットが得られないため、ユニプロセッサ システムで複数のプロセスを生成することは絶対に避けてください。解決しようとしている問題の性質を説明していただければ、さらにお手伝いいたします。
堅牢性が必要な場合は、マルチプロセッシングを使用してください。
プロセスは、プロセス間でロギングの負荷を共有します。遅かれ早かれ、ロギングリクエストはバグにぶつかり、ロガーをクラッシュさせます。マルチプロセッシングでは、1つのプロセスのみが失われるため、その1つのロギングリクエストのみが失われます(バグのため、とにかく処理できませんでした)。
マルチスレッドは、1つの致命的なバグが単一のプロセスを奪うため、クラッシュに対して脆弱です。
マルチ処理は、共有メモリの使用を伴う可能性のあるプロセス間でワークロードのバランスをとる必要があるため、いくつかの点で技術的に困難です。
使用するプログラミング言語 (およびライブラリ) によって異なります。個人的には、スレッドに関連する問題 (およびその解決方法) を知っているので、マルチスレッドを選択します。
複数のマシンでデーモンを実行し、それらの間で負荷を分散したい場合は、マルチプロセッシングが役立つかもしれませんが、それは大きな問題ではないと思います。
更新が頻繁で、IPC のコストが高すぎるインスタンス間で更新データを共有する必要がありますか? その場合、マルチスレッドの方がおそらく優れています。それ以外の場合は、個別のプロセスの堅牢性とスレッドの作成/通信の容易さのどちらが重要かを検討する必要があります。
さて、私たちはついにそれをIPC用のパイプと必要に応じてプロセスを生成する簿記係を備えたマルチプロセスシステムとして実装しました。Apachehttpdに似ています。それは完璧に動作します。
1 つの質問は、どちらかを行う必要があるかどうかです。要件の詳細はわかりませんが、使用する単一のスレッド化されたアプリselect(2)がニーズに合っている可能性があり、プロセスまたはスレッドのいずれの欠点もありません。これには、すべての I/O を 1 つの中央の場所に集中できる必要があり、ほとんどの場合、コールバックを介して他のモジュールにディスパッチしますが、独自の I/O を実行したいライブラリがたくさんない限り、それほど難しくありません。 /O であり、この方法で再構築することはできません。
フィードバックをお寄せいただきありがとうございます。
私は、Apache Web サーバーに似たマルチプロセス アーキテクチャを決定しました。プロセスは、マルチプロセッサ/コア システムで適切にスケーリングされます。通信はパイプまたはソケットで行われます。
プロセスはプロセスプールですぐに使用できるようになるため、プロセスの生成コストはかかりません。
得られる堅牢性に比べれば、パフォーマンスへの影響はごくわずかです。