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

Windows平台Python多进程传递RS232串口对象运行报错问题

报错原因
  • Windows系统下Python的multiprocessing默认使用spawn启动模式,子进程创建时需要将父进程传递的所有参数序列化(pickle)后再传递到子进程反序列化。你在主进程创建的serial.Serial串口对象底层封装了系统级的串口句柄、ctypes指针等无法被序列化的资源,直接传递给子进程时就会触发ctypes objects containing pointers cannot be pickled报错。
  • 第二个PermissionError: [WinError 5] 访问被拒绝是因为Windows系统默认禁止跨进程复制未做特殊标记的硬件资源句柄,即使绕过序列化限制,子进程也没有权限访问父进程创建的串口句柄。
解决方案

方案1:子进程内部初始化串口(最推荐)

不要在主进程创建串口对象,仅将可序列化的串口配置参数传递给子进程,由子进程自行完成串口初始化、数据读取操作,读取到的数据通过multiprocessing.Queue回传给主进程即可。

修改后代码示例

test-main.py

from multiprocessing import Process, Queue
from test_class import test

def main():
    # 仅定义可序列化的串口配置参数
    serial_config = {
        "port": "COM9",
        "baudrate": 9600,
        "parity": "N",
        "stopbits": 1,
        "bytesize": 8,
        "timeout": 0.1
    }
    # 创建队列用于子进程回传串口数据
    data_queue = Queue()
    test_instance = test()
    # 传递配置参数和队列,不传递串口对象
    p = Process(target=test_instance.test_method, args=(serial_config, data_queue))
    p.daemon = True
    p.start()

    # 主进程可以从队列拿子进程传回来的串口数据
    while True:
        if not data_queue.empty():
            data = data_queue.get()
            print("主进程收到串口数据:", data)

if __name__ == '__main__':
    main()

test-class.py

import serial

class test:
    def test_method(self, serial_config, data_queue):
        # 子进程内部初始化串口
        rs232_connection = serial.Serial(**serial_config)
        # 主循环读数据
        while True:
            if rs232_connection.in_waiting:
                data = rs232_connection.readline()
                # 把数据放到队列回传给主进程
                data_queue.put(data)

方案2:改用多线程实现(如果无强制多进程需求)

线程共享同一进程的地址空间,不需要序列化传递资源,直接在主线程初始化串口后传递给子线程即可使用,仅需注意读写串口时加锁避免冲突即可,实现逻辑更简单。

方案3:主进程作为串口代理

如果必须由主进程持有串口对象,可通过队列实现指令中转:子进程需要操作串口时将指令发给主进程,由主进程完成串口读写操作后再将结果回传给子进程。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 02:21:00