Perl fork()共享内存

时间:2013-03-18 13:55:15

标签: perl fork

有没有办法在分叉之前将只读变量加载到内存中并将它们保留在那里而不使用virt memory x 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进程的整个数据结构集?

2 个答案:

答案 0 :(得分: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

其中第二列数字(总体第三列)是系统RAM的总使用量。请注意,在程序开始时分配$data时,它会从2866552增加到2917888,然后在叉子完成时保持相当稳定。

我怀疑你在top中看到的是它在IPC特定的意义上使用“共享内存”(即已明确请求并分配为“共享”的内存块)和当前可在写入时写入多个进程的页面不符合该定义。

答案 1 :(得分:0)

perl docs on fork说“文件描述符(有时锁定那些描述符)是共享的,而其他一切都被复制了。”