5

IO::Socket::INET を使用して、Perl でクライアント サーバー プログラムを作成しました。CGI ベースのサイトからサーバーにアクセスします。サーバー プログラムはデーモンとして実行され、複数の同時接続を受け入れます。私のサーバー プロセスは、約 100MB のメモリ空間を消費します (9 つの大きな配列、多くの配列...)。これらのハッシュをメモリに常駐させて共有し、接続ごとにハッシュを作成する必要がないようにしたいと考えています。ハッシュの作成には 10 ~ 15 秒かかります。

ソケットを介して新しい接続が受け入れられるたびに、新しいプロセスをフォークして、受信した各接続の処理を処理します。親プロセスは巨大であるため、フォークするたびに、プロセッサは新しい子プロセスにメモリを割り当てようとしますが、メモリが限られているため、新しい子プロセスを生成するのに時間がかかり、応答時間が長くなります。1回の接続でも何度もハングアップします。

親プロセスは 9 つの大きなハッシュを作成します。子ごとに、読み取り専用モードで 1 つ以上のハッシュを参照する必要があります。子を通じてハッシュを更新しません。親によって作成された 100 MB 全体またはグローバル変数全体をすべての子と共有できるコピー オン ライトのようなものを使用したいですか? またはスレッドのような他のメカニズム。サーバーは 1 秒あたり最低 100 のリクエストを受け取り、それらすべてを並行して処理できるはずです。平均して、子供は 2 秒で退出します。

Windows XP で Cygwin を使用しており、RAM は 1GB しかありません。この問題を克服する方法が見つかりません。何か提案できますか?変数を共有し、1 秒あたり 100 個の子プロセスを作成して管理し、同期するにはどうすればよいですか?

ありがとう。

4

3 に答える 3

3

フォークの代わりに、同時接続を処理する 2 つの方法があります。スレッドまたはポーリング アプローチのいずれかを使用します。

各接続のスレッド アプローチでは、ソケットの I/O を処理する新しいスレッドが作成されます。スレッドは作成プロセスと同じ仮想メモリで実行され、そのすべてのデータにアクセスできます。ロックを適切に使用して、データへの書き込みアクセスを同期してください。

さらに効率的な方法は、select() によるポーリングを使用することです。この場合、単一のプロセス/スレッドがすべてのソケットを処理します。これは、ほとんどの作業が I/O であり、I/O 要求が完了するのを待つ時間が他のソケットの処理に費やされるという前提の下で機能します。

これら 2 つのオプションについてさらに調査し、どちらが最適かを判断してください。

例を参照してください: http://www.perlfect.com/articles/select.shtml

于 2008-12-11T12:04:47.743 に答える
2

このアーキテクチャはCygwinには適していません。実際のUNIXシステムでのフォークは安価ですが、Cygwinのような偽のUNIXシステムでは、すべてのデータをコピーする必要があるため、非常に高価です(実際のUNIXではコピーオンライトを使用します)。スレッドを使用すると、メモリ使用パターンが変更されます(基本使用量は多くなりますが、スレッドあたりの増加は少なくなります)が、それでも非効率になる可能性があります。

ポーリングを使用した単一プロセスのアプローチを使用することをお勧めします。おそらく、非ブロッキングIOも使用します。

于 2008-12-11T16:15:25.647 に答える
2

それだけのデータがあるのに、なぜ単純にデータベースを使わないのだろうか。

于 2008-12-11T14:18:51.873 に答える