代码之家  ›  专栏  ›  技术社区  ›  Genarito

Python 3.9中的进程在ThreadPoolExecutor中创建时退出,代码为1

  •  0
  • Genarito  · 技术社区  · 5 年前

    我有一段代码可以将任务提交给 ThreadPoolExecutor 这就开始了 Process .我意识到,在Python 3.8中,这个过程以退出代码结束 0 .但我已经将Python更新到了3.9版本,并开始以退出代码结束 1 ! 即使进程执行空任务。

    下面是一个简单的例子:

    from multiprocessing import Process
    from concurrent.futures import ThreadPoolExecutor
    
    
    def some_task():
        pass
    
    
    def execute_error():
        p = Process(target=some_task)
        p.start()
        p.join()
        print(p.exitcode)  # This is always 1 on a ThreadPoolExecutor!!!
    
    
    executor = ThreadPoolExecutor(max_workers=4)
    executor.submit(execute_error)
    # execute_error()  # IMPORTANT: this works correctly (exit 0)
    

    我的版本:

    Ubuntu 21.04
    Python 3.9.4
    

    笔记 如果 __execute_error 在ThreadPoolExecutor外部调用它可以正常工作。有我失踪的地方吗?这是Python 3.9的错误吗?有什么解决办法吗?任何形式的帮助都将不胜感激

    0 回复  |  直到 5 年前
        1
  •  1
  •   xjcl    5 年前

    这个 multiprocessing 模块提供3种启动流程的方法: spawn , fork forkserver .我猜您使用的是基于Unix的系统,默认为 方法文件

    注意安全 分叉多线程进程是有问题的 .

    • 在通话现场复制发生上述问题的整个过程。
    • 产卵 从头开始创建一个新的Python进程,并将所需的资源传递给它。
    • forkserver 创建一个单线程服务器进程,该进程将用作模板,以从中派生未来的进程。因为它是单螺纹的,所以这种叉子是安全的。

    根据我的测试和描述, 任选一个 产卵 forkserver exitcode 0 .

    from multiprocessing import Process, set_start_method
    set_start_method('spawn')
    

    从Python 3.8到3.9的回归 然而,方法让我担心,所以我离开了 a comment 在Python bug追踪器上。也许有人会解决这个问题,但正如我所说的,就文档而言,分叉多线程进程是不受支持的。