2011-01-12 16 views
2

私は主な「消費者」プロセスが、ディスクからデータを読み取り、それを「消費者」に渡して表示する一連の「リーダー」プロセス(〜16)を作り出すLinuxアプリケーションを作成しました。データは、socketpairを使用してフォークの前に作成されたソケットを介して渡されます。共有メモリを使用している場合、スレッディングよりもプロセスに利点はありますか?

私はもともと3つの理由でこのプロセス境界でそれを書いた:

  1. 消費者プロセスは、リアルタイムの制約を持っているので、私は消費者のいずれかのメモリ割り当てを避けたかったです。読者は自由にメモリを割り当てたり、別の言語(例えば、ガベージコレクション)で書かれていても、FIFOの優先順位を持つ消費者を中断させることはありません。また、読者プロセスにおけるディスクアクセスまたは他のIOは、消費者を妨害しない。私はスレッドで私はそのような保証を得ることができないと考えました。

  2. プロセスを使用すると、プログラマは、グローバル変数を使用したり、他のプロセスのメモリを壊すような愚かなことをやめてしまいます。

  3. 複数のCPUアーキテクチャーを利用する最良の方法はたくさんありますが、スレッドの代わりにプロセスを使うのが一般的に安全だと思いました。

すべての読者が常にアクティブであるわけではありませんが、アクティブな人は常に大量のデータを送信しています。最近、私は、ソケットの書き込みと読み取りに関連するメモリコピーを避けることでこれを最適化することを考えていました。データを共有メモリバッファ(shm_open/mmap)に直接読み込むといいでしょう。この共有メモリーへの索引のみがソケットを介して渡され、消費者はそれを再び利用可能とマークする前にそれを直接読み取ることになります。

とにかく、スレッドに対するプロセスの最大の利点の1つは、へのの別のスレッドのメモリ空間の破壊です。共有メモリへの切り替えは、私がこのアーキテクチャで持っている利点を破壊すると思いますか?このコンテキストでプロセスを使用する利点はありますか?または、スレッドを使用するようにアプリケーションを切り替えるだけですか?

答えて

3

スレッドでリアルタイムの制約を満たすことができないという前提は誤っています。消費者スレッドがmalloc自身を使用していない限り(ロック競合に繋がる可能性がある)、読者スレッドのIOまたはメモリ割り当ては、消費者スレッドを停止させることはできません。もし私が不確かならば、POSIXのことを読むことをお勧めします。

スレッドの代わりにプロセスを使用する他の理由(安全性、異なる言語での読者の書き込み可能性など)に関しては、これらは完全に合法です。コンシューマプロセスが共有メモリバッファを潜在的に安全でない外部データとして扱う限り、パイプから共有メモリに切り替えることで大きな安全性を失うとは思いません。

+0

本当に?どういうわけか、 'malloc'が' sbrk'を使ってヒープサイズを拡張する必要があると感じると、プロセス全体が停止する可能性があるという印象を受けました。同様に、スレッドがページ違反を生成するメモリ操作を行っている場合、プロセス内のすべてのスレッドを停止させる可能性があります。多分それは間違っている? – Steve

+0

それは間違っています。スレッドを停止させるだけです。厳密に言えば、これは実装の詳細です(おそらくPOSIXリアルタイムオプションに準拠しているシステムを除いています)。しかし、正常な実装ではこれらの操作で他のスレッドをストールすることはできません。確かにLinux、BSD、そして他の主流のUnixでは、それは単にスレッドが停止するだけです。 –

+0

さて、ありがとう、情報ありがとうございます。 – Steve

-1

スレッドでプロセスを置き換えるために私が経験した主な理由は効率でした。 プロセスが、マルチスレッドで共有できるコードまたは共有されていないメモリをたくさん使用している場合、SUN Sparc CPUのようにCPUあたり64以上のスレッドを持つ高度にスレッド化されたCPUで多くのパフォーマンスを得ることができます。この場合、特にコードのCPUキャッシュは、マルチスレッドプロセス(キャッシュはSparcでは小さい)ではるかに効率的になります。

新しいハードウェアでより多くのCPUスレッドを実行しているときに、ソフトウェアの実行速度が向上しない場合は、マルチスレッドを考慮する必要があります。それ以外の場合、それを避けるあなたの議論は私にとっては良いようです。

Intelプロセッサではまだこの問題は発生しませんでしたが、将来、CPUごとにコアを追加すると発生する可能性があります。

+0

archtectureが物理的にマップされたキャッシュ(SPARCとx86/x86-64 doの両方)を使用している限り、複数のプロセスにマップされた同じコードセグメントは同じキャッシュ優先順位を持ちます。 – caf

0

はい、あなたが言ったのとまったく同じです。各プロセスのメモリを保護し、共有するために本当に必要なものだけを共有する方が良いです。したがって、各消費者は、ロックを気にすることなくリソースを割り当てて使用することができます。

あなたのタスク間のインデックス通信に関しては、ソケット通信よりも重視されない可能性があるため、共有メモリ内の領域をそれに使用し、アクセスにmutexを使用することができます。ファイルディスクリプタの通信(ソケット、パイプ、ファイルなど)には常にカーネル、ミューテックスロックまたはセマフォを持つ共有メモリが関与します。

マルチプロセッサ環境で共有メモリを使用してプログラミングを行う場合、変数に対する誤った依存関係を回避することが重要です。これは、関係のない2つのオブジェクトが同じキャッシュラインを共有している場合に発生します。一方が変更されたときに他方が "ダーティー"になると、他のプロセッサが他のオブジェクトにアクセスすると、CPU間のキャッシュ同期がトリガーされます。これはスケーリングが悪くなる可能性があります。オブジェクトをキャッシュ・ライン・サイズ(通常は64バイトですが、アーキテクチャごとに異なる場合があります)に合わせることで、オブジェクトを簡単に回避できます。

関連する問題