ws_*_*421 6 python io terminate
当进程终止时,Python 中的文件对象会发生什么?SIGTERMPython 以、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
Run Code Online (Sandbox Code Playgroud)
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
Run Code Online (Sandbox Code Playgroud)
我使用termtest.sh不同的信号运行(更改SIGTERM为SIGINT、SIGHUP和SIGKILLin termtest.sh)(注意:我在termtest.pyfor中放入了一个显式处理程序SIGINT,因为 Python 除了 as 之外不处理该信号Ctrl+C)。在所有情况下,所有输出文件都只有完整的行(没有部分写入)并且没有出现损坏。我放置了flush()和fsync()调用来尝试确保数据尽可能多地写入磁盘,以便脚本在写入过程中有最大的机会被中断。
那么我是否可以得出这样的结论:Python 在终止时总是完成写入并且不会使文件处于中间状态?或者这取决于操作系统和文件系统(我正在使用 Linux 和 ext4 分区进行测试)?
问题不在于文件如何“清理”,而在于文件如何写入。程序可能会对单个数据“块”(行或其他)执行多次写入,并且您可能会在此过程的中间中断并最终写入部分记录。
查看该模块的C 源代码csv,它将每一行组装到一个字符串缓冲区,然后使用单个write()调用将其写入。这通常应该是安全的;该行要么被传递到操作系统,要么不被传递,如果它到达操作系统,则全部都会被写入,或者不会被写入(当然,除非出现硬件问题,其中一部分可能会进入坏扇区)。
writer 对象是一个 Python 对象,自定义 writer 可以在其中做一些奇怪的事情write(),这可能会破坏它,但假设它是一个常规文件对象,应该没问题。
| 归档时间: |
|
| 查看次数: |
1201 次 |
| 最近记录: |