在Python Flask中对某些文件运行多线程会出现ValueError:对关闭的文件进行I/O操作

问题描述 投票:0回答:1

我正在尝试在响应 api 请求时执行 python 脚本,但脚本需要一些时间来执行,因此我尝试返回响应并使用多线程同时运行脚本。但我给了我这个错误。** ValueError:关闭文件上的 I/O 操作。** 这是我的请求代码

def post(self,var1=None,var2=None):
        args=self.createDoc_args.parse_args()
        doc_file=args['doc']
        doc_filetype=doc_file.filename.split('.')[1]
        doc_filename=doc_file.filename.split('.')[0]
        csv_file=args['csv']
        df = pd.read_csv(csv_file, header=None)
        csv_filetype=csv_file.filename.split('.')[1]
        if csv_filetype!='csv':
            MySqlDatabase.close_connection(self.cursor, self.db)
            abort(http_status_code=406, message="Please Upload .csv File")

        
        status_id=1
        # Get the current time
        current_time = dt.datetime.now()

    # Add 5 minutes to the current time
        new_time = current_time + dt.timedelta(minutes=5)
        query="INSERT INTO doc (title, doc, csv, date_created,status_id,eta) VALUES (%s,%s,%s,%s,%s,%s)"
        val=(doc_filename+'.'+doc_filetype,doc_file.read(),csv_file.read(),dt.datetime.today(),status_id,new_time) 
        self.cursor.execute(query,val)
        doc_id=self.cursor.lastrowid
        #Commit changes and close connection
        self.db.commit()
        q = queue.Queue()
        q.put((doc_file, df))
        MySqlDatabase.close_connection(self.cursor, self.db)
        thread = threading.Thread(target=custom_code, args=(q, ))
        thread.start() 
        return jsonify(message='Your blog is being generated')

此代码运行脚本

def custom_code(queue):
    doc_file, df = queue.get()
    # This is the code you want to run after a specific request
  
    print(df,"junaid")
    response=write_Article(doc_file,df)
    print(response)

我认为问题在于参数中的文件,因为主函数返回响应。主函数中的所有文件都被关闭,这会引发错误。

multithreading flask flask-restful
1个回答
0
投票

当您尝试从已关闭的文件中读取时,会发生错误。

在您的代码中,您将

doc_file
df
传递给线程内的
custom_code
函数,但文件在线程可以访问它们之前就已关闭

要避免此问题,您需要确保线程运行时文件保持打开状态,请尝试以下方法:

  1. 不传递文件对象,而是将文件内容传递给线程:

替换

post
函数中的这一行:

q.put((doc_file, df))

这样:

q.put((doc_file.read(), df))
  1. 修改
    custom_code
    函数接收文件内容:

替换

custom_code
函数中的这一行:

doc_file, df = queue.get()

这样:

doc_contents, df = queue.get()
  1. 更新您的自定义代码以使用
    doc_contents
    而不是
    doc_file
    :

替换

custom_code
函数中的这一行:

response = write_Article(doc_file, df)

这样:

response = write_Article(doc_contents, df)

通过进行这些更改,您将把文件内容传递给线程,确保在线程执行您的

custom_code
时文件保持打开状态。

© www.soinside.com 2019 - 2024. All rights reserved.