多进程启动报错:logger cannot be pickled与EOFError: Ran out of input问题排查求助
解决多进程中pyshark LiveCapture与DataFrame的序列化问题
你遇到的两个错误本质上都是多进程参数序列化失败引发的,我来帮你拆解问题并给出可行的解决方案:
错误原因分析
PicklingError: logger cannot be pickled
Windows系统下的multiprocessing默认使用spawn模式,这种模式要求所有传递给子进程的参数都必须能被pickle序列化。而你传给子进程的cap1是pyshark.LiveCapture对象,它内部包含了无法被序列化的logger实例,直接传递就会触发这个错误。EOFError: Ran out of input
这个错误是第一个序列化失败的连锁反应——子进程尝试加载父进程传递的序列化数据时,因为前面的PicklingError导致数据不完整,所以抛出了"读不到输入"的异常。
另外还有个隐性问题:你直接传递df_sspd给子进程,子进程里的df.append()操作只会修改自己的内存副本,主进程根本看不到任何变化,因为多进程间的内存是相互隔离的。
解决方案
核心思路是避免传递不可序列化的对象,同时使用多进程安全的共享数据结构:
修改后的代码示例
import pyshark from multiprocessing import Process, Manager import pandas as pd def get_data(interface, filter_str, shared_list): # 子进程内部独立创建LiveCapture实例,不依赖父进程传递 cap = pyshark.LiveCapture(interface=interface, display_filter=filter_str) for packet1 in cap.sniff_continuously(packet_count=100): print("ssdp") packet_len = len(packet1) print(packet_len) # 往共享列表里添加数据,所有进程都能访问到 shared_list.append(packet_len) print(len(shared_list)) if __name__ == '__main__': # 使用Manager创建多进程安全的共享列表 with Manager() as manager: shared_packet_lengths = manager.list() # 传递可序列化的参数(字符串、共享列表),而非LiveCapture或DataFrame sspd_p = Process(target=get_data, args=('1', 'ssdp', shared_packet_lengths)) sspd_p.start() sspd_p.join() # 等待子进程完成数据采集 # 最后在主进程中将共享列表转为DataFrame df_sspd = pd.DataFrame(shared_packet_lengths, columns=['packet_length']) print(df_sspd)
关键修改点
- 子进程独立创建LiveCapture:不再从父进程传递这个不可序列化的对象,每个子进程自己初始化抓包实例,彻底避免序列化问题。
- 使用Manager共享数据:
Manager.list()是多进程安全的容器,子进程添加的数据主进程能实时获取,解决了多进程内存隔离的问题。 - 主进程统一处理DataFrame:DataFrame的操作放在主进程中,避免跨进程传递和修改DataFrame带来的额外问题。
这样修改后,你的两个错误都会消失,同时也能正确收集抓包数据到DataFrame里。
内容的提问来源于stack exchange,提问作者user1977050
相关产品推荐
相关产品推荐

