当前位置: 首页 > 面试题库 >

使用try语句如何避免出现竞争情况?

尉迟龙光
2023-03-14
问题内容

在确定文件是否存在时,使用try语句如何避免“竞争条件”?

我之所以这样问是因为高度支持的答案0)(更新:已删除)似乎暗示使用os.path.exists()会创造机会,否则这种机会就不会存在。

给出的示例是:

try:
   with open(filename): pass
except IOError:
   print 'Oh dear.'

但与以下内容相比,我不了解如何避免出现竞争状况:

if not os.path.exists(filename):
    print 'Oh dear.'

调用如何os.path.exists(filename)使攻击者能够处理他们无法完成的文件?


问题答案:

比赛条件,当然,你的程序和文件上运行一些其他的代码之间(竞争状态总是需要至少两个平行的进程或线程,看到这个细节)。这意味着仅在以下两种情况下使用open()而不是exists()可能真正有用:

  1. 您检查是否存在由某些后台进程创建或删除的文件(但是,如果您在Web服务器中运行,则通常意味着您的进程有很多副本并行运行以处理HTTP请求,因此对于Web应用程序来说,即使没有其他程序,也可能出现这种情况)。
  2. 可能有一些正在运行的恶意程序正在尝试通过在您希望文件存在的时刻破坏文件来破坏您的代码

exists()只需执行一次检查。如果文件存在,则可以在exists()返回后一微秒内将其删除True。如果没有文件,则可以立即创建。

但是,open()不仅要测试文件是否存在,还要打开文件(并且自动执行这两个操作,因此在检查和打开之间不会发生任何事情)。通常,当有人打开文件时,无法将其删除。这意味着with您可能会完全确定:由于文件已打开,因此它现在确实存在。尽管只有在内部才是正确的with,并且在with块退出后仍可能会立即删除文件,但是将需要文件存在的with代码放入其中可以确保代码不会失败。



 类似资料:
  • 问题内容: 我正在开发的应用程序中存在潜在的竞争状况,我想在查询中考虑和避免这种情况。 总结应用程序流程… 在表中创建一个新行: 通过查看对时间敏感的表格,找出Bar先生是否是获胜者: 如果他是赢家,请相应地更新他的条目行: 由于每个奖项只能颁发一次,因此我需要消除比赛条件的任何可能性,在这种情况下,另一个过程可以查询奖项表并更新上述步骤2和3之间的条目表。 我一直在做一些研究,发现了大量关于事务

  • 问题内容: 我的问题是我必须在try语句中设置变量,否则会出现编译错误。 稍后我需要使用该变量,但现在超出了范围,所以我相信。我在try语句外部初始化了该变量并将其设置为null,我以为可以在外部访问它,但仍然得到了。 下面的代码,其中有很多代码使阅读变得更容易-我知道这是不好的代码,但是我是Servlets的新手,只想看看它与所有活动部件一起运行时应如何工作。 我创建了另一个类,该类调用crea

  • 我有一个分布式任务队列,其中的任务如下所示: 这里有一个竞争条件:如果任务队列软件在完全相同的时间启动其中两个任务,它们都将从数据库中获得相同的<code>old_path</code>,并且竞争失败者的取消链接调用失败(将失败者的新路径从未来的取消链接中孤立出来)。 有没有办法让我构建它来绕过这场比赛?如果需要,我可以从当前设计中抛出几乎任何东西。具体来说,我使用的是PostgreSQL,Pyt

  • 我正在使用Java Spring框架和Hibernate。我正在做一个电子商务web应用程序,其中公共用户可以从web应用程序购买产品。每个产品都有一个数量计数。 问题 1)我想确认这个关于悲观锁定的答案有助于解决我的问题。 2)我的工作流程正常吗?有没有更好的方法?

  • 我不清楚它写在哪里 私有构造函数的存在是为了避免将复制构造函数实现为此(p.x,p.y)时出现的争用条件;这是私有构造函数捕获习惯用法的一个例子(Bloch和Gafter,2005)。 我知道它提供了一个getter来在数组中同时检索x和y,而不是为每一个单独的getter,所以调用者将看到一致的值,但为什么是私有构造函数呢?这里有什么诀窍

  • 这闻起来很难闻: 永远不会调用“u”大小写,因为是。 我如何重写它,使我只有三个分支? 理想情况下,我还想删除199/200, 599/600和999/1000/0的重复。 如果最好的解决方案不是,我很乐意使用其他一些控制结构。