关于python:TypeError:init()缺少1个必需的位置参数:’message’使用Multiprocessing

TypeError: init() missing 1 required positional argument: 'message' using Multiprocessing

我正在使用多处理池运行一段代码。代码在一个数据集上工作,在另一个数据集上失败。很明显,问题是由数据驱动的——我说我不清楚从哪里开始故障排除,因为我收到的错误如下。任何关于起点的提示都是最有用的。这两组数据都是用同一个代码准备的——所以我不希望有什么不同——但我在这里。

另请参见罗伯特的评论——我们在操作系统和Python3.6版(我有3.4版,他有3.6版)上有所不同,数据集也非常不同。然而,错误与Python代码中的行完全相同。

我的怀疑:

  • 每个内核都有一个强制的内存限制。
  • 在一段时间之后,这个过程就开始收集——发现这个过程并没有结束,也没有放弃。

    线程9中的异常:

    回溯(最近一次呼叫的最后一次):

    文件"c:program filespythonwinpython-64bit-3.4.4.4qt5python-3.4.4.amd64lib hreading.py",第911行,位于u bootstrapu innerSun()

    文件"C:Python Python WiPython 64位-3.4.4.4QT5python 3.4.4. AMD64 LIB thord.py.',行859,在运行中自我。目标(*自我。

    文件"c:program filespythonwinpython-64bit-3.4.4.4qt5python-3.4.4.amd64libmultiprocessingpool.py",第429行,in_handle_results任务= GET()

    文件"C:Program Filespythonwinpython-64bit-3.4.4.4qt5python-3.4.4.amd64libmultiprocessingconnection.py",第251行,在recv中返回ForkingPickler.Loads(buf.getBuffer())

    类型错误:init()缺少1个必需的位置参数:"message"


  • 我认为问题在于,langdetect在这里悄悄地声明了一个隐藏的全局探测器工厂:https://github.com/mimino666/langdetect/blob/master/langdetect/detector_factory.py l120:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    def init_factory():
        global _factory
        if _factory is None:
            _factory = DetectorFactory()
            _factory.load_profile(PROFILES_DIRECTORY)

    def detect(text):
        init_factory()
        detector = _factory.create()
        detector.append(text)
        return detector.detect()


    def detect_langs(text):
        init_factory()
        detector = _factory.create()
        detector.append(text)
        return detector.get_probabilities()

    根据我的经验,这类事情可能会导致多处理中的问题,因为多处理试图在进程之间共享内存中的资源,并管理工作进程和主进程中的命名空间,尽管在这种情况下,确切的机制对我来说是一个黑盒。我通过向我的池初始化函数添加对init_factory函数的调用来修复它:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    from langdetect.detector_factory import init_factory
    def worker_init_corpus(stops_in):
        global sess
        global stops
        sess = requests.Session()
        sess.mount("http://", HTTPAdapter(max_retries=10))
        stops = stops_in
        signal.signal(signal.SIGINT, signal.SIG_IGN)
        init_factory()

    仅供参考:"sess"逻辑是为每个工作人员提供一个用于请求的HTTP连接池,以解决在将该模块与多处理池一起使用时出现的类似问题。如果不这样做,工作人员会通过父进程备份所有HTTP通信,因为默认情况下,隐藏的全局HTTP连接池就位于此位置,然后一切都会非常缓慢。这是我遇到的一个问题,使我怀疑这里有类似的原因。

    另外,为了进一步减少潜在的混淆:stops用于提供我用于映射函数的停止字列表。而signal调用是在用户中断时强制池很好地退出(ctrl-c)。否则,他们往往会成为孤儿,在父进程死后继续苟延残喘。

    然后我的池初始化如下:

    1
    self.pool = mp.Pool(mp.cpu_count()-2, worker_init_corpus, (self.stops,))

    在一个TI/catch EDCOX1×4块中,我还把我的调用封装到EDCOX1×3中:

    1
    2
    3
    4
    try:
        posting_out["lang"] = detect(posting_out["job_description"])
    except LangDetectException:
        posting_out["lang"] ="none"

    但这并不能单独解决。很有信心初始化就是修复。


    多亏了罗伯特-专注于语言检测,我发现可能有一个文本条目是空的。

    langdetectexception:文本中没有功能

    新秀的错误-可能是由于编码错误-过滤掉错误后重新运行-将保持你(罗伯特)张贴。