1

フォークする前に読み取り専用変数をメモリにロードし、virtメモリx子の数を使い果たすことなくそれらを保持する方法はありますか?

読み取り専用メモリはデフォルトで共有され、書き込み時にコピーされるというのが一般的な意見のようです。テストを実行したところ、これは正しくないことがわかりました。

#!/usr/bin/perl

my $data;
$$data = 'a'x 1_000_000; #keep it in a ref just in case that matters

foreach (0..10){
    last unless my $pid = fork();
}   
<STDIN>;

プロセスがSTDINにある間、私はトップをチェックします:

  PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND   

15982 wdev      20   0  121m 2540  188 S  0.0  0.1   0:00.00 foo.t                             
15983 wdev      20   0  121m 2540  188 S  0.0  0.1   0:00.00 foo.t                             
15984 wdev      20   0  121m 2540  188 S  0.0  0.1   0:00.00 foo.t                             
15985 wdev      20   0  121m 2540  188 S  0.0  0.1   0:00.00 foo.t                             
15986 wdev      20   0  121m 2540  188 S  0.0  0.1   0:00.00 foo.t                             
15987 wdev      20   0  121m 2540  188 S  0.0  0.1   0:00.00 foo.t                             
15988 wdev      20   0  121m 2540  188 S  0.0  0.1   0:00.00 foo.t                             
15989 wdev      20   0  121m 2540  188 S  0.0  0.1   0:00.00 foo.t                             
15990 wdev      20   0  121m 2540  188 S  0.0  0.1   0:00.00 foo.t                             
15991 wdev      20   0  121m 2540  188 S  0.0  0.1   0:00.00 foo.t                             
15992 wdev      20   0  121m 2540  188 S  0.0  0.1   0:00.00 foo.t  

案の定、事実上すべてのメモリは個々の子プロセスにあります。

私が見逃しているものはありますか、またはperlプロセスをフォークすると、各子のデータ構造のセット全体が実際にコピーされますか?

4

2 に答える 2

3

これはオペレーティングシステムに依存しているか、表示されていると思われるものが表示されていません。テストスクリプトを次のように変更しました。

#!/usr/bin/env perl    

print `free`;

my $data = [ ('a') x 1000000 ];

for (1 .. 10) {
  print `free`;
  last unless fork;
} 

sleep 10;

で実行すると./forktest | grep Mem、次のような出力が得られます。

Mem:       3979908    2866552    1113356          0     667388    1258560
Mem:       3979908    2917888    1062020          0     667388    1258560
Mem:       3979908    2918284    1061624          0     667388    1258560
Mem:       3979908    2918532    1061376          0     667388    1258560
Mem:       3979908    2918936    1060972          0     667388    1258560
Mem:       3979908    2919404    1060504          0     667388    1258560
Mem:       3979908    2919900    1060008          0     667388    1258560
Mem:       3979908    2919900    1060008          0     667388    1258560
Mem:       3979908    2920148    1059760          0     667388    1258560
Mem:       3979908    2920148    1059760          0     667388    1258560
Mem:       3979908    2920496    1059412          0     667388    1258560

ここで、数値の2番目の列(全体の3番目の列)は、システムRAMの合計使用量です。プログラムの開始時に割り当てられると、2866552から2917888に増加し$data、フォークが完了すると、それ以降はかなり安定していることに注意してください。

あなたが見ているtopのは、IPC固有の意味での「共有メモリ」(つまり、明示的に要求され、「共有」として割り当てられたメモリのチャンク)と、現在複数のプロセスで使用可能なページを使用していることだと思います。コピーオンライトベースでは、その定義を満たしていません。

于 2013-03-18T15:29:39.563 に答える
0

forkに関するperl ドキュメントには、「ファイル記述子 (および場合によってはそれらの記述子のロック) が共有され、他のすべてがコピーされる」と書かれています。

于 2013-03-18T14:31:30.287 に答える