TypeError: cannot pickle ‘_io.TextIOWrapper‘ object multiprocessing调用pexpect

本文介绍使用pexpect模块连接bluetoothctl时遇到的进程间通信问题及解决方案。当尝试将pexpect.spawn创建的进程传递给multiprocessing时会出现无法pickling错误。通过在每个子进程中重新实例化bluezcon类来解决此问题。

报错:TypeError: cannot pickle '_io.TextIOWrapper' object

创建一个class用pexpect.spawn连接bluetoothctl

import sys
import logging
import pexpect
from multiprocessing import Pool
 
logger = logging.getLogger()


class bluezcon():
    def __init__(self, promt='#', logfile=None):
        app = 'bluetoothctl'
        startexpectstr='Agent registered'
        self.promt = promt
        self.startpexpect(app=app, expect=startexpectstr, logfile=logfile)

    def startpexpect(self, app, expect=None, logfile=None):
        cmdlist = []
        cmdlist.append(app)
        cmd = ' '.join(cmdlist)
        self.spawn_cmd = cmd
        logger.debug(f"start pexpect subprocess: {cmd}")
        self.process = pexpect.spawn(cmd, timeout=30, logfile=logfile, encoding="utf-8", echo=False)
        self.process.logfile_read = sys.stdout
        if not expect:
            expect = self.promt
        self.process.expect(expect)

    def sendcommand(self, cmd, expect=None, timeout=2):
        self.process.buffer = ''
        if not expect:
            expect = self.promt
        self.process.sendline(cmd)
        self.process.expect(expect, timeout=timeout)
        return True

在主进程实例bluezcon, 代入multiprocessing

if __name__ == '__main__':
    pool = Pool(processes=2)
    bt = bluezcon()
    result = pool.apply_async(bt.sendcommand, ('show',))
    pool.close()
    pool.join()
    print(result.get())

运行结果

test$ python3 test.py
Agent registered
Traceback (most recent call last):
  File "/home/test/test.py", line 48, in <module>
    print(result.get())
  File "/usr/lib/python3.10/multiprocessing/pool.py", line 774, in get
    raise self._value
  File "/usr/lib/python3.10/multiprocessing/pool.py", line 540, in _handle_tasks
    put(task)
  File "/usr/lib/python3.10/multiprocessing/connection.py", line 206, in send
    self._send_bytes(_ForkingPickler.dumps(obj))
  File "/usr/lib/python3.10/multiprocessing/reduction.py", line 51, in dumps
    cls(buf, protocol).dump(obj)
TypeError: cannot pickle '_io.TextIOWrapper' object

主进程的pexpect.spawn 不能带入到multiprocessing子进程中。尝试用Queue去传递,得到相同报错。

解决办法

在子进程中,实例bluezcon

def test():
    bt = bluezcon()
    bt.sendcommand('show')


if __name__ == '__main__':
    pool = Pool(processes=2)
    result = pool.apply_async(test)
    pool.close()
    pool.join()
    print(result.get())

结果

test$ python3 test.py
Agent registered
Controller 64:BC:58:17:C1:5D (public)
        Name: dev-01
        Alias: dev-01
        Class: 0x007c0104
        Powered: yes
        Discoverable: no
        DiscoverableTimeout: 0x0000001e
        Pairable: yes
        UUID: Message Notification Se.. (00001133-0000-1000-8000-00805f9b34fb)
        UUID: A/V Remote Control        (0000110e-0000-1000-8000-00805f9b34fb)
        UUID: OBEX Object Push          (00001105-0000-1000-8000-00805f9b34fb)
        UUID: Message Access Server     (00001132-0000-1000-8000-00805f9b34fb)
        UUID: PnP Information           (00001200-0000-1000-8000-00805f9b34fb)
        UUID: IrMC Sync                 (00001104-0000-1000-8000-00805f9b34fb)
        UUID: Headset                   (00001108-0000-1000-8000-00805f9b34fb)
        UUID: A/V Remote Control Target (0000110c-0000-1000-8000-00805f9b34fb)
        UUID: Generic Attribute Profile (00001801-0000-1000-8000-00805f9b34fb)
        UUID: Phonebook Access Server   (0000112f-0000-1000-8000-00805f9b34fb)
        UUID: Audio Sink                (0000110b-0000-1000-8000-00805f9b34fb)
        UUID: Device Information        (0000180a-0000-1000-8000-00805f9b34fb)
        UUID: Generic Access Profile    (00001800-0000-1000-8000-00805f9b34fb)
        UUID: Handsfree Audio Gateway   (0000111f-0000-1000-8000-00805f9b34fb)
        UUID: Audio Source              (0000110a-0000-1000-8000-00805f9b34fb)
        UUID: OBEX File Transfer        (00001106-0000-1000-8000-00805f9b34fb)
        Modalias: usb:v1D6Bp0246d0541
        Discovering: no
        Roles: central
        Roles: peripheral
Advertising Features:
        ActiveInstances: 0x00 (0)
        SupportedInstances: 0x08 (8)
        SupportedIncludes: tx-power
        SupportedIncludes: appearance
        SupportedIncludes: local-name
        SupportedSecondaryChannels: 1M
        SupportedSecondaryChannels: 2M
        SupportedSecondaryChannels: Coded
[dev-2]# None

参考:

(96条消息) 小黑受到了封校的恐惧,秋招结束该何去何从的日常积累:进程初步_小黑无敌的博客-CSDN博客python - pexpect runs failed when use multiprocessing - Stack Overflow

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值