如果我们不在Perl中关闭文件有多严重?

Daa*_*ish 6 perl file-io file-handling

如果我们不在Perl中关闭文件有多严重?如果我在同一个程序中再次访问它会影响程序或文件吗?

amo*_*mon 13

全局文件句柄将保持不变,直到您的程序退出.这可能不好,但是你可能不应该使用全局文件句柄,这不是问题.

当左边的范围/它们的引用计数降到零时,它们的词法文件句柄myclosed.

如果重新使用文件句柄的名称,则close隐含地使用先前的文件句柄.以下脚本重用相同的文件句柄来打印任意数量文件的前五行:

my $fh;
foreach my $filename (@ARGV) {
  open $fh, "<", $filename or die "Can't open $filename";  # $fh is re-used
  print scalar <$fh> // next for 1 .. 5;                   # // is the defined-or
}
Run Code Online (Sandbox Code Playgroud)

使用文件时,明确关闭FH并不重要.但是,在进行IPC时这一点至关重要.将写入结束关闭到管道表示读取端的EOF.

forking时,应关闭所有未使用的文件句柄,因为它们在分叉时是重复的.这意味着在一个进程中关闭管道可能不会发送所需的EOF,因为相同的管道仍然在相关进程中打开.

这是一个演示closeIPC 重要性的程序:

pipe my $out, my $in or die $!;

if (fork()) {  # PARENT
  close $out;                            # close unused handle    (important!)
  select $in;
  $| = 1;                                # set $in to autoflushed (important!)
  $SIG{PIPE} = sub {die "Parent"};       # die, when the pipe is closed
  print ++$i, "\n" and sleep 1 while 1;  # print one number per second
} else {       # CHILD
  close $in;                             # close unused handle
  print scalar <$out> for 1 .. 5;        # read numbers 1 to 5 from the pipe
  close $out;                            # close the pipe (and trigger SIGPIPE)
  sleep 5;                               # wait, then exit
  die "Child";
}
Run Code Online (Sandbox Code Playgroud)

该程序的输出是数字1到5.然后,子项关闭管道的末尾,SIGPIPE在父项中触发.当父母去世时,孩子会徘徊5秒钟直到它死亡.

这是有效的,因为父级将其读取端关闭到管道.如果close $out从父项中删除,则SIGPIPE不会触发,并且程序无限制地打印数字.