Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/qt/7.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Perl中不关闭目录句柄意味着什么?_Perl_Syntax Error - Fatal编程技术网

在Perl中不关闭目录句柄意味着什么?

在Perl中不关闭目录句柄意味着什么?,perl,syntax-error,Perl,Syntax Error,我最近继承了一些别人写的代码 我发现,在代码中打开目录以供读取的任何地方,都没有关闭目录,因为原始开发人员有语法问题-他使用close函数尝试关闭目录句柄,而不是closedir函数 代码是这样的: opendir( DIR, $dir ) or die "Cannot open $dir: $!\n"; @files = readdir( DIR ); close( DIR ); (这是Perl最佳实践(第208278页)中关于检查close函数的返回的另一个好观点。如果在这种情况下检查cl

我最近继承了一些别人写的代码

我发现,在代码中打开目录以供读取的任何地方,都没有关闭目录,因为原始开发人员有语法问题-他使用
close
函数尝试关闭目录句柄,而不是
closedir
函数

代码是这样的:

opendir( DIR, $dir ) or die "Cannot open $dir: $!\n";
@files = readdir( DIR );
close( DIR );
(这是Perl最佳实践(第208278页)中关于检查
close
函数的返回的另一个好观点。如果在这种情况下检查
close
的返回,它将失败,并显示“错误的文件号”。)

后来我将其更改为
closedir
,但这让我开始思考:既然目录句柄从未关闭,那么长时间打开目录句柄会带来什么负面影响

该程序较大(3500行代码),运行一段时间(5-10分钟),并且该程序的多个实例同时运行。对于上面示例中的此目录,
$dir
对于所有实例都是相同的值。如果此程序的10个实例同时运行,则它们都对同一目录持有一个开放目录句柄5分钟或更长时间。我确信Perl会在程序完成时自动关闭目录句柄,但最佳实践是尽快关闭它

对我来说,更明显的是,如果文件句柄保持打开状态会导致问题(特别是对于为写入而打开的文件句柄),但是如果不关闭目录句柄,会发生什么不好的事情呢

我问这个问题的原因是因为有一个奇怪的情况,这个程序试图创建一个文件(在上面$dir定义的目录中)。文件名中嵌入了PID,因此文件可能已经存在的可能性较小,但Perl无法打开文件进行编写,因为它说文件已经存在。当我们查看目录时,该文件不存在。我想知道这个目录上的所有开放目录句柄是否都会导致这样的问题

我不确定操作系统是否起作用,但这个程序正在AIX上运行


提前谢谢,星期五快乐

您浪费了一个目录描述符—它可能被算作文件描述符。如果您的程序打开了足够多的目录以耗尽文件描述符,那么最终会对您造成伤害。否则,它是相当无害的,虽然不太理想。它使系统(和Perl)保留资源,否则它可能会释放这些资源

如果目录句柄是一个局部变量,而不是一个普通的DIR样式名称,那么您可能需要Perl来清理它。看哪个说:

打开名为EXPR的目录,以供readdir、telldir、seekdir、rewinddir和closedir处理。如果成功,则返回true。DIRHANDLE可以是一个表达式,其值可以用作间接DIRHANDLE,通常是真正的DIRHANDLE名称。如果DIRHANDLE是未定义的标量变量(或数组或散列元素),则会为该变量分配一个对新匿名DIRHANDLE的引用。DIRHANDLEs有自己的名称空间,与FILEHANDLEs分开


不会有任何严重的后果。从内核本身来看,内存使用会略微增加,内核本身无法释放内部用于循环遍历目录项列表的迭代器,可能还会从perl端释放内存

另外,只要目录的任何描述符仍然打开,就不能从文件系统中实际删除数据。如果其他外部进程将删除您拥有句柄的目录,它将不再出现在未来的目录列表中,但数据仍必须保留在磁盘上,并且仍然可以通过打开句柄的进程访问。例如,这可能会导致磁盘使用率出现奇数

还请注意,您不必手动关闭所有句柄。使用词法文件句柄时,一旦对句柄的最后一次引用消失,就会自动关闭:

 { # new scope
     opendir(my $handle, ...) or ...;
     ...
 } # implicit closedir happens here

这是一堂始终使用词法文件(和目录)句柄的课——词法句柄在超出范围时会自动关闭


所以,如果1,那么您只会浪费描述符(正如Jonathan所描述的)。您使用了老式的球形手柄,或2。所有代码都在一个平面脚本中,没有子例程或其他作用域。使用良好的编程实践,意外错误会更少:)

即使在今天,一些操作系统对文件描述符也相当吝啬(我正在看你,solaris,你的默认设置是64-256)。@mobrule-很抱歉,我不能发表你的评论,因为没有可用的文件描述符-真诚地,StackOverflow Solaris后端…此opendir位于主目录中,因此它是全局范围的。。。但是你绝对正确-良好的编程实践肯定会减少无意中的错误!根据你的代码,你使用了一个裸字句柄。除非您显式地将它们本地化,否则它们始终是全局范围的。