在有条件的一段时间内测试文件存在是不是有任何陷阱?
Posted
技术标签:
【中文标题】在有条件的一段时间内测试文件存在是不是有任何陷阱?【英文标题】:Are there any pitfalls to testing for file existence in a while conditional?在有条件的一段时间内测试文件存在是否有任何陷阱? 【发布时间】:2011-05-13 11:24:43 【问题描述】:我最近遇到了一行有趣的代码,它会等到某个特定的文件恢复正常:
sleep 1 until -e $file;
虽然从表面上看,这条线符合人们的预期,但我不禁觉得这里有些不对劲;编写以下内容似乎更自然:
while (1)
sleep 1;
last if -e $file;
文件测试运算符是否仅用于if
和unless
?在while
条件中部署此类操作符是否有任何性能损失?
【问题讨论】:
性能???这里唯一的惩罚是 ping 文件系统,这比任何循环都要大一个数量级...... @Drakosha :您希望典型的文件 ping 需要多长时间?一秒钟的睡眠还不足以对抗延迟吗? 是的,看起来在任何普通文件系统/存储上都有足够的时间。我只是不明白你为什么要检查循环性能,这里可以忽略不计。 【参考方案1】:在 while-true (while
) 与 while-false (until
) 循环中使用文件测试运算符或使用 if
/unless
分离测试之间没有区别,与 Perl 中的其他任何东西也没有区别。
while 循环的唯一神奇情况是 ... while <$handle>;
或 while (<$handle>) ...
在定义时将 $_
设置为下一行。并且使用带有裸句柄的 while-false (until
) 循环并没有真正的意义。
a until b
结构就是a while not b
。
要将sleep 1 until -e $file;
转换为while
循环,您可以使用以下代码:
sleep 1 while not -e $file;
这可以扩展为块形式:
while (not -e $file) sleep 1
或者作为带有内部转义的无限while
:
while (1)
last if -e $file;
sleep 1;
所有这些形式都是等价的。
回答您的其余问题,大多数文件系统应该可以在两次检查之间休眠 1 秒,但如果进程没有紧急等待文件,您可以通过多种方式选择更大的数字。此外,如果您使用的设备文件系统速度较慢(存储在闪存中或通过慢速网络),您可能还需要尝试更大的值。
正如下面的ysth
nitpicks,一般来说,当语句形式是返回的构造的最后一个元素时,它们的返回方式与块形式不同:do ...
、sub ...
、do FILE
、eval ...
【讨论】:
@Eric :我更感兴趣的是比较在while
条件中使用文件测试而不是if
条件。 until
/while not
等价不是这里的问题。
@Zaid => 这是同一个问题,文件测试,就像布尔上下文中的任何其他操作一样,在循环内的条件(if
)与条件循环(@ 987654346@)
@Zaid:从你的“看起来更自然”来看,听起来它使用 until 语句修饰符让你感到困扰。
直到略有不同:比较 print do sleep 1 until -e $file
和 print do while (not -e $file) sleep 1
@ysth :until
的使用一点也不困扰我。将until
与文件测试一起使用即可。我还没有遇到将文件测试与循环条件结合使用的示例。【参考方案2】:
即使文件存在,您更自然的方式似乎也是在开始时休眠。
while(not -e $file) sleep 1;
对我来说似乎更好,这正是 sleep 1 until -e $file;
的同义词,但在我看来更容易理解。
【讨论】:
不是一个确切的同义词;一个会返回 false,一个会返回 true。以上是关于在有条件的一段时间内测试文件存在是不是有任何陷阱?的主要内容,如果未能解决你的问题,请参考以下文章
将 Cassandra 集群部署到一组 Linode VPS 实例是不是有任何“陷阱”?