使用pexpect和多重处理时出错?错误“ TypError:无法序列化'_io.TextIOWrapper'对象”

我在Linux计算机上有一个Python 3.7脚本,该计算机试图在多个线程中运行一个函数,但是当我尝试时,出现以下错误:

Traceback (most recent call last):
  File "./test2.py",line 43,in <module>
    pt.ping_scanx()
  File "./test2.py",line 39,in ping_scanx
    par = Parallel(function=self.pingx,parameter_list=list,thread_limit=10)
  File "./test2.py",line 19,in __init__
    self._x = self._pool.starmap(function,parameter_list,chunksize=1)
  File "/usr/local/lib/python3.7/multiprocessing/pool.py",line 276,in starmap
    return self._map_async(func,iterable,starmapstar,chunksize).get()
  File "/usr/local/lib/python3.7/multiprocessing/pool.py",line 657,in get
    raise self._value
  File "/usr/local/lib/python3.7/multiprocessing/pool.py",line 431,in _handle_tasks
    put(task)
  File "/usr/local/lib/python3.7/multiprocessing/connection.py",line 206,in send
    self._send_bytes(_ForkingPickler.dumps(obj))
  File "/usr/local/lib/python3.7/multiprocessing/reduction.py",line 51,in dumps
    cls(buf,protocol).dump(obj)
TypeError: cannot serialize '_io.TextIOWrapper' object

这是我用来演示该问题的示例代码:

#!/usr/local/bin/python3.7
from multiprocessing import Pool
import pexpect   # Used to run SSH for sessions

class Parallel:

    def __init__(self,function,thread_limit=4):

        # Create new thread to hold our jobs
        self._pool = Pool(processes=thread_limit)

        self._x = self._pool.starmap(function,chunksize=1)

class PingTest():

    def __init__(self):
        self._pex = None

    def connect(self):
        self._pex = pexpect.spawn("ssh snorton@127.0.0.1")

    def pingx(self,target_ip,source_ip):
        print("PING {} {}".format(target_ip,source_ip))

    def ping_scanx(self):

        self.connect()

        list = [['8.8.8.8','96.53.16.93'],['8.8.8.8','96.53.16.93']]

        par = Parallel(function=self.pingx,thread_limit=10)


pt = PingTest()
pt.ping_scanx()

如果我未在pexpect.spawn中包含该行,则不会发生该错误。有人可以解释为什么我得到此错误,并提出解决方法吗?

qqwainier1 回答:使用pexpect和多重处理时出错?错误“ TypError:无法序列化'_io.TextIOWrapper'对象”

实际上,您使用multiprocessing.Pool将函数作为单独的进程而不是线程进行调用。进程无法共享Python对象,除非它们先进行序列化,然后再通过进程间通信通道相互传输,这是multiprocessing.Pool在后​​台使用pickle作为序列化程序为您完成的工作。由于pexpect.spawn将终端设备作为类似文件TextIOWrapper的对象打开,因此您要将返回的对象存储在PingTest实例中,然后将绑定方法self.pingx传递给Pool.starmap,它将尝试序列化self,该序列在pexpect.spawn属性中包含_pex对象,不幸的是,由于TextIOWrapper不支持序列化,该对象无法序列化。

由于函数是受I / O约束的,因此您应该通过multiprocessing.dummy模块使用线程化,以提高并行效率,在这种情况下更重要的是,允许pexpect.spawn对象在线程,无需序列化。

更改:

from multiprocessing import Pool

收件人:

from multiprocessing.dummy import Pool

演示:https://repl.it/@blhsing/WiseYoungExperiments

本文链接:https://www.f2er.com/3135628.html

大家都在问