EOFError:在 Python 中进行多处理时出现输入错误

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

我正在尝试使用 python 中的

gallery_dl
库编写一个下载管理器,但我遇到了多处理问题(用于在 Web-ui 接口中管理多个下载任务)。

当我尝试在

__init__
类的
DownloadTask
方法中创建新作业时,出现
self = reduction.pickle.load(from_parent) ... EOFError: Ran out of input
错误。

我猜这是因为

multiprocessing
正在使用
pickle
来序列化子进程中的内容,而
pickle
无法处理
gallery_dl
实例,但我不知道该怎么办。

有办法解决或解决这个问题吗?

这是我的代码的简化版本:

# DownloadManager.py
from typing import Dict
from DownloadTask import DownloadTask
import uuid
import multiprocessing

class DownloadManager:
    def __init__(self):
        self.tasks: Dict[str, DownloadTask] = {}
        self.processes: Dict[str, multiprocessing.Process] = {}

    def add_task(self, url: str) -> str:
        task_id = str(uuid.uuid4())
        new_task = DownloadTask(task_id, url)
        self.tasks[task_id] = new_task

        task_process = multiprocessing.Process(target=new_task.start)
        self.processes[task_id] = task_process
        task_process.start()

        return task_id

if __name__ == '__main__':
    downloader = DownloadManager()
    downloader.add_task("https://lexica.art/?q=cats")
# DownloadTask.py
from gallery_dl import job

class DownloadTask:
    def __init__(self, task_id: str, url: str):
        self.task_id = task_id
        self.url = url
        self.job = job.DownloadJob(url)

    def start(self):
        self._download()

    def _download(self):
        self.job.run()

我尝试直接在

DownloadManager
实例上的
DownloadTask
类中创建作业,但仍然出现相同的错误。

我还尝试将作业初始化为

None
并在
start
类的
DownloadTask
方法中创建它。但这样我以后就无法通过其他方法访问该作业(我需要在暂停/恢复方法中访问该作业)

from gallery_dl import job

class DownloadTask:
    def __init__(self, task_id: str, url: str):
        self.task_id = task_id
        self.url = url
        self.job = None  # init as None

    def start(self):
        self.job = job.DownloadJob(self.url) # create the job instance
        self._download()

    def _download(self):
        self.job.run()
    
    def pause(self):
        print(self.job) # will print None
        # actual pause code
python multiprocessing pickle
1个回答
0
投票

尝试在

job.DownloadJob
中创建
start()
,这似乎是一个子进程,而不是在您的
__init__()

中实例化它

这是一个代码片段来说明我的意思

 def start(self):
   # Create the DownloadJob inside the process
     self.job = job.DownloadJob(self.url)
     self._download()

 def _download(self):
     if self.job:
        self.job.run()

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