[kansaipm] use & fork

Dan Kogai dankogai at dan.co.jp
Fri Oct 3 10:25:52 CDT 2003


On Friday, Oct 3, 2003, at 15:05 Asia/Tokyo, SUGITA Toshinori wrote:
> このMLには初の投稿になります。
> デジタルパッド 杉田と申します。

弾です。はじめまして。

> もし、このMLにふさわしくない話題であれば、ご指摘下さい。
>
> 現在、perl5.8 にて以下のようなアプリケーションを作ろうと思っています。
> プラットホームはUnix系です。
>
> 1. ユーザー権限でデーモン起動する。
> 2. 外部のプロセスからデーモンに対して、リクエストを受け付ける。
>    pipeまたはunix socketを想定。
> 3. リクエストに応じてデーモンはサブプロセスをforkし、その中で処理を
>    おこない、pipeまたはunix socket経由でレスポンスを返す
>
> 具体的には、apacheからcgiまたはfastcgiを通じて、ネットワーク経由の
> リクエストを受け付け、リクエストで指定されたスクリプトをデーモンで
> 実行してレスポンスを返す、というものを作りたいと思っています。

これであれば、わざわざdaemonでやるより、mod_perlなどを使ってapacheの中でやってしまう方が早いかもしれません。

> 問題になっているのは、forkしたときの use (というよりは require)の
> 動作です。
> レスポンスを早く返すために出来る限りレスポンスごとのコンパイル量を
> 減らしたいのですが、forkした後に use を実行すると、コンパイル結果は
> forkしたプロセスが終了した時点で消えてしまいます。

これは、よくある require と use に対する誤解です。requireと違って、useは実行<前>に評価されるので、たとえ  
script の一番最後に use していても、すでに評価済みなので、すでに親processが実行された時点で終わっています。

例えば、

defined (my $pid = fork()) or die;
if ($pid == 0){ # child
   do_child()
   #
}else{          # parent
   #
}
sub do_child{
   use Module_For_Child;
   #
}

というcodeでも、Module_For_Child.pm の評価は、実際にdo_childが呼ばれる前に終わっているのです。

> いくつか考えてみたのですが、どうもしっくり来るものがありません。

これらは実は特効薬はなく、実際の開発の現場では、プロトタイプを作って評価試験をやって決める場合が多いです。fork()の重さ一つとっても、環境 
によってまちまちです。

経験上は、この手のプロジェクトは、下手にserverを作るより、mod_perlで内部的に直接やる方が速いことが多いですが、認証系が絡むと 
mod_perlの神通力も通用しないこともあります(mod_perlのmoduleはhttpdのUID/GIDに縛られてしまうので)。

しかしその前に、use に対する誤解があるところから見ても、performance  
tuning以前のレベルに失礼ながら私には見えてしまうのですが。

まず、スピードはさておき動くものを作ってみましょう。その後で、どこを optimize するかを考えても遅くおそくありません。

You can sometimes write faster codes in C, but you can always write  
codes faster in Perl
-- Larry Wall

Dan the Man with Too Many Codes (by Others) to Optimize




More information about the Kansai-pm mailing list