我有一个文件,我知道它正好是 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"
我唯一能想到的是我在某处的内存不足。 "测试文件"的填充来自后台的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)
行是为了防止竞争条件。
您不是在等待后台任务完成。尝试在打开testfile
之前将执行的while
循环替换为以下内容:
pid.wait()
其中pid
是来自subprocess.Popen()
的回报。
作为替代方案,您可以一举创建文件。例如,您可以创建testfile.tmp
,然后在子流程中运行mv testfile.tmp testfile
。
您有一个进程写入文件,另一个进程读取同一文件。在多处理系统上,如果没有进程间同步,您将获得争用条件,因此计数低于预期。这与实现语言无关。
管道在进程间同步方面做得很好。命令:
$ producer | tee testfile | wc -l
将始终通过wc
准确输入testfile
行数来生成精确计数。你让这个问题变得比它应该的要困难得多。