编辑

时间:2018-03-08 02:51:02

标签: python windows python-multiprocessing python-multithreading ioerror

我在Windows上并希望运行我的多线程python应用程序,以异步方式将数据保存到.csv。根据报告hereherehere,我在某个时候收到以下错误:

<type 'exceptions.IOError'> 
Traceback (most recent call last):
  File "results_path", line 422, in function
    df_results.to_csv(results_file)
IOError: [Errno 24] Too many open files

This提出了一个修复程序,其中包含每个文件IO操作的with语句:

with open(results_path, 'a') as results_file:
         df_results.to_csv(results_file)

但是,我仍然如上所述得到IOError简而言之,所有问题都没有解决我的问题)。因此,with - 语句显然在追加操作后没有正确关闭.csv文件。

首先,我现在增加了打开文件的数量。这无疑只是推迟了崩溃:

import win32file
max_open_files = 2048     # Windows-specific threshold for max. open file count
win32file._setmaxstdio(max_open_files)

其次,我的临时方法是(A)来连续检查打开的.csv文件,(B)如果打开文件计数则强行重启整个脚本得到任何接近Windows允许的阈值:

from psutil import Process 
import os, sys
proc = Process() 
open_file_count = 0                                         # Set up count of open files
for open_file in proc.open_files():                         # Iterate open files list
        if ".csv" in str(open_file):                        # Is file of .csv type?
                open_file_count += 1                        # Count one up
            else:
                continue
    else:
        if open_file_count > (max_open_files / 2):              # Threshold, see above
            os.execl(sys.executable, sys.executable, *sys.argv) # Force restart
        else:
            pass

这种方法在许多方面都是丑陋且低效的(在每个迭代/线程中循环遍历所有打开的文件)。至少,这需要在不强行重启整个代码的情况下工作。

Q1:如何在Windows上使用python正确关闭.csv文件?

Q2:如果在IO操作后关闭失败,如何强制关闭一次打开所有.csv文件?

3 个答案:

答案 0 :(得分:1)

这些答案是正确的。 with语句是正确的和Pythonic方式来打开和自动关闭文件。它有效并且很好测试。但是,我怀疑它是多功能处理程序或线程程序,它正在投入扳手。

特别是,有多少线程或进程正在写入您的CSV?如果不止一个,那么我对这个问题充满信心。相反,拥有一个编写器,并通过multiprocessing.Queue或常规(线程安全)队列传递需要写入该编写线程或进程的内容。实际上是一个漏斗,其中所有想要向CSV添加数据的进程都会将数据放入队列中,并且写入过程将把每个队列项取出并将其写入文件。

鉴于问题中缺乏工作示例,我只需在multiprocess communication上留下指向Python文档的指针。

答案 1 :(得分:1)

使用https://docs.python.org/3/library/concurrent.futures.html中的ThreadPoolExecutor,这样您可以保持一次运行的最大线程数小于文件描述符的最大数量。

with语句是处理文件关闭的最佳方式,即使异常发生也不会忘记。

答案 2 :(得分:0)

接近正常,而不是“与”???

In [1]: import pandas as pd

In [2]: df = pd.DataFrame()

In [3]: fw = open("test2.txt","a")

In [4]: df.to_csv(fw)

In [5]: fw.close()

In [6]: !ls
test2.txt