读取同时写入的文件时计数不准确

时间:2013-11-11 22:54:38

标签: python

我知道的文件正好是7168行。在各种条件下,我得到虚假行数。举个例子:

file = open("testfile", 'r')
count = 0
for line in file:
   count += 1
   print "count: " + str(count)

此代码导致: “数: 1098

file = open("testfile", 'r')
count = 0
for line in file:
   count += 1
   print line  ### this line is the only difference
   print "count: " + str(count)

此代码导致: “数: 7168

我能想到的唯一一件事就是我在某个地方耗尽了记忆。 “testfile”的人口来自背景中的Popen。想法/希望是在用户到达脚本中需要完成转储的点之前,将所有必需的数据转储到后台文件中。如果用户到达脚本中需要testfile内容的点,但Popen尚未完成,则运行以下代码:

notified = False
while (os.path.getsize("testfile") == 0):
   if notified == False:
      print "Please hold, still dumping uids..."
      notified = True
print "done!"

怀疑将os.path.getsize立即召唤数千次可能是有害的,我修改了我的代码:

notified = False
while (os.path.getsize("testfile") == 0):
   if notified == False:
      print "Please hold, still dumping uids..."
      notified = True
   time.sleep(3)   ### Delay 3 seconds
print "done!"

这个的情况下,我的行计数为 6896 (这是非常好的,但仍然不是真正的计数)

进一步修改:

notified = False
while (os.path.getsize("testfile") == 0):
   if notified == False:
      print "Please hold, still dumping uids..."
      notified = True
   time.sleep(5)   ### Delay 5 seconds
print "done!"

现在,我的行计数按预期显示为 7168

任何人都可以向我解释发生了什么,以及如何以更高的效率实现我的目标?总体目标是,我的脚本需要在脚本的某个时刻将大量数据转储到文件中。为了减少用户的停机时间,我的Popen在脚本开始时在后台运行。 while (os.path.getsize("testfile") == 0)行是为了防止竞争条件。

2 个答案:

答案 0 :(得分:3)

您不是在等待后台任务完成。在打开while

之前,请尝试替换正在执行的testfile循环
pid.wait()

其中pidsubprocess.Popen()的回报。


作为替代方案,您可以一举创建该文件。例如,您可以创建testfile.tmp,然后在子流程中运行mv testfile.tmp testfile

答案 1 :(得分:1)

您有一个进程正在编写文件而另一个进程正在读取同一个文件。在多处理系统上,没有进程间同步,您将获得竞争条件,因此计数低于预期。这与实现语言无关。

管道在进程间同步方面做得很好。命令:

$ producer | tee testfile | wc -l

将始终按wc精确计算放入testfile的行数。你使这个问题比它应该更难。