Python多进程示例中Worker进程未被调用问题排查
这个问题我之前在Windows下用Python多进程时也碰到过,核心和多进程启动机制以及输出缓冲有关。先给你梳理可以排查的位置,再讲问题根源和修复方案:
一、可以添加打印语句的排查点
- 在
PseudoThing.__init__方法开头添加打印(记得先导入os模块):print(f"Initializing PseudoThing with address: {self.address}, pid: {os.getpid()}", flush=True),确认子进程是否重新初始化了对象 - 在
worker方法的第一行就加打印:print(f"Entering worker function, pid: {os.getpid()}", flush=True),验证子进程是否真的进入了这个方法 - 在
get_address_type函数内添加打印:print(f"Checking address type for: {address}", flush=True),看子进程是否调用了这个函数 - 在
attach方法的开头和分支里加打印,比如print("Running attach method", flush=True),跟踪执行路径 - 在模块最顶部(import语句之后)添加打印:
print(f"Module loaded, __name__: {__name__}, pid: {os.getpid()}", flush=True),这样能看到子进程启动时是否重新导入了模块
二、问题的核心原因
你碰到的情况是两个原因叠加导致的:
- Windows多进程的
spawn启动机制:Python 3在Windows上默认用spawn方式启动子进程,这种方式会重新导入主模块,通过序列化传递对象给子进程。虽然你的代码已经把启动逻辑放在if __name__ == "__main__":里避免了无限递归,但子进程的输出可能因为缓冲问题没及时显示。 - stdout缓冲导致输出丢失:默认情况下Python的
print是行缓冲的,但你的worker方法第一次循环就会因为self.server被赋值为"hello!"直接退出,子进程快速结束时,缓冲的打印内容还没来得及刷新到控制台就被销毁了,所以你看不到子进程的输出。
三、修复方案
最直接的解决方式是给子进程中的print语句加上flush=True参数,强制刷新输出缓冲。修改后的worker方法示例:
def worker(self): print("in worker!", flush=True) for i in range(10): print(f"I'm a worker doing worker things... iteration {i}", flush=True) self.attach() if self.server: print("Worker exiting with server set", flush=True) return True time.sleep(0.2)
测试修改后的代码,你就能看到子进程的打印内容了,输出大概是这样:
doing main! starting process in worker! I'm a worker doing worker things... iteration 0 Worker exiting with server set __name__ = __main__
内容的提问来源于stack exchange,提问作者bzm3r
相关产品推荐
相关产品推荐

