
python 的 multiprocessing 无法直接序列化绑定方法(如 `obj.method`),因其依赖于不可跨进程传递的实例引用;正确做法是将逻辑封装为可调用函数,或确保实例创建和方法调用均发生在子进程中。
在使用 multiprocessing.Process 时,目标函数(target)必须是可被 pickle 序列化的对象——这是进程间传递函数和参数的基础。而类的绑定实例方法(例如 instance.method)在默认情况下无法被正确序列化,因为 self 引用指向的是父进程中的内存对象,子进程无法访问该地址空间。
你最初尝试的代码存在两个关键问题:
- 方法定义缺失 self 参数:def sleeper(sec): 是一个静态签名,但被声明为实例方法(无 @staticmethod 装饰),导致调用时参数不匹配;
- 错误地试图跨进程传递已绑定方法:sleepingClass.sleeper 是一个绑定方法对象,其底层包含对父进程实例的引用,无法安全传输到子进程。
✅ 正确解法是:让实例的创建和方法调用都发生在子进程中,而非在主进程中创建实例再传入。这样每个进程拥有独立的内存副本,避免序列化瓶颈。
以下是推荐的三种实践方式:
立即学习“Python免费学习笔记(深入)”;
✅ 方式一:在目标函数中创建并调用实例(最推荐)
import multiprocessing
import time
class SleepingClass:
def __init__(self, sec):
self.sec = sec
def sleeper(self):
print(f'sleeping for {self.sec} seconds...')
time.sleep(self.sec)
def run_sleeper(sec):
# 子进程中创建实例并执行
instance = SleepingClass(sec)
instance.sleeper()
if __name__ == "__main__":
process = multiprocessing.Process(target=run_sleeper, args=(2,))
process.start()
process.join() # 等待完成,便于观察输出✅ 方式二:使用 functools.partial 预设参数(适用于简单场景)
from functools import partial
import multiprocessing
import time
class SleepingClass:
def __init__(self, sec):
self.sec = sec
def sleeper(self):
print(f'sleeping for {self.sec} seconds...')
time.sleep(self.sec)
if __name__ == "__main__":
# 注意:不能直接传 sleepingClass.sleeper!
# 而应通过工厂函数 + partial 构造可序列化目标
def create_and_run(sec):
SleepingClass(sec).sleeper()
process = multiprocessing.Process(target=create_and_run, args=(3,))
process.start()
process.join()⚠️ 注意事项
- ❌ 不要尝试 pickle 绑定方法(如 pickle.dumps(obj.method)),会抛出 AttributeError 或 TypeError;
- ✅ 所有共享数据需通过 multiprocessing.Queue、multiprocessing.Pipe 或 multiprocessing.Manager 显式传递;
- ✅ 始终在 if __name__ == "__main__": 下启动进程,尤其在 Windows 上防止递归创建子进程;
- ✅ 使用 process.join() 同步主进程,避免主程序提前退出导致子进程被终止。
总结:多进程不是“复制对象”,而是“复制执行环境”。把类实例的生命周期限制在单个进程中,是保证健壮性和可移植性的核心原则。










