我有一个运行很长时间的python脚本,它会创建和删除临时文件。我注意到在文件删除上花费了不小的时间,但是删除这些文件的唯一目的是确保该程序最终不会在长期运行时填满所有磁盘空间。 Python中是否存在跨平台机制来异步删除文件,以便在操作系统负责文件删除的同时主线程可以继续工作?

最佳答案

您可以尝试将删除文件委托(delegate)给另一个线程或进程。

使用新产生的线程:

thread.start_new_thread(os.remove, filename)

或者,使用一个过程:
# create the process pool once
process_pool = multiprocessing.Pool(1)
results = []

# later on removing a file in async fashion
# note: need to hold on to the async result till it has completed
results.append(process_pool.apply_async(os.remove, filename), callback=lambda result: results.remove(result))

进程版本可能允许更多的并行性,因为臭名昭著的global interpreter lock导致Python线程无法并行执行。我希望GIL在调用任何阻塞的内核函数(例如unlink())时被释放,以便Python让另一个线程取得进展。换句话说,调用os.unlink()的后台工作线程可能是最佳解决方案see Tim Peters' answer

但是,multiprocessing使用下面的Python线程与池中的进程进行异步通信,因此需要进行一些基准测试才能确定哪个版本提供了更多的并行性。

避免使用Python线程但需要更多编码的另一种方法是生成另一个进程,并通过管道将文件名发送到其标准输入。这样,您就可以将os.remove()交易为同步的os.write()(一个write()系统调用)。可以使用不推荐使用的os.popen()来完成此操作,此功能的使用非常安全,因为它仅在一个方向上与子进程进行通信。一个可行的原型(prototype):
#!/usr/bin/python

from __future__ import print_function
import os, sys

def remover():
    for line in sys.stdin:
        filename = line.strip()
        try:
            os.remove(filename)
        except Exception: # ignore errors
            pass

def main():
    if len(sys.argv) == 2 and sys.argv[1] == '--remover-process':
        return remover()

    remover_process = os.popen(sys.argv[0] + ' --remover-process', 'w')
    def remove_file(filename):
        print(filename, file=remover_process)
        remover_process.flush()

    for file in sys.argv[1:]:
        remove_file(file)

if __name__ == "__main__":
    main()

关于python - 我可以在Python中异步删除文件吗?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/19056837/

10-09 16:23
查看更多