You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python multiprocessing:apply_async调用类方法与传递对象问题

多进程apply_async调用类方法及传递对象参数的问题解决

核心问题分析

多进程间存在内存隔离,子进程操作的是主进程对象的副本,修改副本不会直接同步到主进程;另外,Windows系统的spawn模式下,实例方法、不可序列化对象(如mp.Pool)的传递会导致任务无法执行。


一、调用类方法的修改方案

问题原因

直接传递c1.foo作为目标函数时,在spawn模式下无法被正确序列化,导致子进程无法执行该方法。

修改后代码

import multiprocessing as mp

class myClass():
    def __init__(self, id):
        self.id = id
        self.val = 1.0
        self.pool = None

    def callback(self, obj):
        self.val = obj.val

    def foo(self, new_val):
        print('foo passed with', new_val)
        self.val = new_val
        return self

if __name__ == '__main__':
    c1 = myClass('c1')
    c1.pool = mp.Pool(processes=1)
    # 改为传递类方法+实例作为参数,避免序列化问题
    c1.pool.apply_async(myClass.foo, args=(c1, 2.0, ), callback=c1.callback).wait()
    c1.pool.close()
    c1.pool.join()
    print('c1.val:', c1.val)

解释

通过myClass.foo明确指定类方法,同时将实例c1作为第一个参数传入,解决实例方法序列化的问题。子进程执行方法后修改副本的val并返回,主进程的callback方法将原实例的val更新为副本的val,得到预期结果。


二、传递对象作为参数的修改方案

问题原因

原代码中myClass包含mp.Pool类型的pool属性,而Pool对象不可被序列化,导致传递c1作为参数时序列化失败,子进程无法执行任务。

修改后代码

import multiprocessing as mp

class myClass():
    def __init__(self, id):
        self.id = id
        self.val = 1.0
        self.pool = None

    def __getstate__(self):
        # 序列化时移除不可被pickle的pool属性
        state = self.__dict__.copy()
        del state['pool']
        return state

    def __setstate__(self, state):
        # 反序列化时恢复属性,pool设为None
        self.__dict__.update(state)
        self.pool = None

    def callback(self, obj):
        self.val = obj.val

def foo(obj, new_val):
    print('foo passed with', new_val)
    obj.val = new_val
    return obj

if __name__ == '__main__':
    c1 = myClass('c1')
    c1.pool = mp.Pool(processes=1)
    c1.pool.apply_async(foo, args=(c1, 2.0, ), callback=c1.callback).wait()
    c1.pool.close()
    c1.pool.join()
    print('c1.val:', c1.val)

解释

通过__getstate__和__setstate__方法控制对象的序列化过程,移除不可序列化的pool属性,确保c1能被正常传递到子进程。子进程修改副本的val后返回,主进程的callback同步更新原实例的val,得到预期结果。


内容的提问来源于stack exchange,提问作者Saad

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.12 15:41:12