読者です 読者をやめる 読者になる 読者になる

Starlet 0.24で子プロセスごとに乱数系列が初期化されるようになった

Perl 5で fork する場合に乱数系列が親と同じになってしまう現象については過去にもいろいろエントリがあります。

0.23以前の Starlet では、親で一度でもどこかで rand (またはsrand) が呼ばれていると、初期化された乱数系列が fork された子プロセスにも引き継がれるため、その後に実際のユーザアプリケーションが走る子プロセス内で rand() しても同じ系列が返ってきてしまう、という現象があったのですが、0.24 では子プロセス生成後に srand() が呼ばれるようになりました。
# 正確にいうと、0.14 で --min-reqs-per-child がサポートされたタイミングで「--min-reqs-per-child が指定されている場合のみ」srand() が呼ばれていたのですが、それがデフォルトの動作になりました。

なので POSIX::AtFork でごにょごにょとか、アプリケーション側での対処は不要になっています。

Starlet 同様にポピュラーな prefork タイプの実装である Starman では、以前から子プロセスの初期化処理で srand() が呼ばれています。

注意点としては、各子プロセスで乱数系列が同じことを期待しているアプリケーションは挙動が変わってしまいますが、普通ないですよね…? その場合は個別に同一引数で srand を実行して揃えればよいかと思います。

kazuho++