【发布时间】:2016-07-28 09:12:34
【问题描述】:
当进程终止时,Python 中的文件对象会发生什么? Python 是否以SIGTERM、SIGKILL、SIGHUP(等)或KeyboardInterrupt 异常终止是否重要?
我有一些日志记录脚本,它们不断获取数据并将其写入文件。我不关心做任何额外的清理工作,但我只想确保在 Python 突然终止时日志文件没有损坏(例如,我可以让它在后台运行并关闭计算机)。我制作了以下测试脚本来尝试看看会发生什么:
termtest.sh:
for i in $(seq 1 10); do
python termtest.py $i & export pypid=$!
sleep 0.3
echo $pypid
kill -SIGTERM $pypid
done
termtest.py:
import csv
import os
import signal
import sys
end_loop = False
def handle_interrupt(*args):
global end_loop
end_loop = True
signal.signal(signal.SIGINT, handle_interrupt)
with open('test' + str(sys.argv[-1]) + '.txt', 'w') as csvfile:
writer = csv.writer(csvfile)
for idx in range(int(1e7)):
writer.writerow((idx, 'a' * 60000))
csvfile.flush()
os.fsync(csvfile.fileno())
if end_loop:
break
我使用不同的信号运行termtest.sh(在termtest.sh 中将SIGTERM 更改为SIGINT、SIGHUP 和SIGKILL)(注意:我在termtest.py 中为SIGINT 放置了一个显式处理程序因为除了Ctrl+C 之外,Python 不处理那个。在所有情况下,所有输出文件都只有完整的行(没有部分写入)并且没有出现损坏。我调用了flush() 和fsync() 以确保尽可能多地将数据写入磁盘,以便脚本在写入过程中最有可能被中断。
那么我是否可以得出结论,Python 在终止时总是会完成写入并且不会使文件处于中间状态?还是这取决于操作系统和文件系统(我使用 Linux 和 ext4 分区进行测试)?
【问题讨论】: