python TypeError:在结合多处理程序使用生成器时无法腌制生成器对象

时间:2018-07-08 03:46:43

标签: python multiprocessing generator

我有一个fun()函数,它由yields生成。我想检查生成器是否为空,并且由于我想节省尽可能多的运行时间,所以我 不要将其转换为列表,并检查其是否为空。 相反,我这样做:

def peek(iterable):
    try:
        first = next(iterable)
    except StopIteration:
        return None
    return first, itertools.chain([first], iterable)

我这样使用多重处理:

def call_generator_obj(ret_val):
    next = peek(ret_val)
    if next is not None:
        return False
    else:
        return True


def main():
    import multiprocessing as mp
    pool = mp.Pool(processes=mp.cpu_count()-1)
    # for loop over here
        ret_val = fun(args, kwargs)
        results.append(pool.apply(call_generator_obj, args=(ret_val,))
        # the above line throws me the error

据我所知,酸洗是将内存中的某些对象转换为字节流时进行的,而我在任何函数中都在做类似的事情。

回溯:(在尖线之后)

  File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/multiprocessing/pool.py", line 253, in apply
    return self.apply_async(func, args, kwds).get()
  File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/multiprocessing/pool.py", line 608, in get
    raise self._value
  File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/multiprocessing/pool.py", line 385, in _handle_tasks
    put(task)
  File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/multiprocessing/connection.py", line 206, in send
    self._send_bytes(_ForkingPickler.dumps(obj))
  File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/multiprocessing/reduction.py", line 51, in dumps
    cls(buf, protocol).dump(obj)
TypeError: can't pickle generator objects

1 个答案:

答案 0 :(得分:1)

  

据我所知,酸洗是在将内存中的某些对象转换为字节流时进行的,我认为我在这里没有做类似的事情。

好吧,你正在这样做。

您不能在进程之间直接传递Python值。即使是最简单的变量,也会在该进程的内存空间中的某个位置保留一个指向结构的指针,而仅将该指针复制到另一个进程将给您一个段错误或垃圾,这取决于另一个进程中的同一内存空间是未映射还是映射到完全不同的东西。像生成器这样复杂的东西(基本上是活动堆栈框架)将更加不可能。

text = "NC don’t like working together www.linktowtweet.org" text = re.sub(r'https?:\/\/.*[\r\n]*', '', text, flags=re.MULTILINE) #to remove any URL text = text.split() #splits sentence into words with delimiter=" " last_word = text[-1] 解决问题的方法是透明腌制您传递给它的所有内容。函数及其参数及其返回值都需要被腌制。

如果您想了解其幕后工作原理,则multiprocessing的工作原理是让Pool上级工作Queue,而父级put的任务基本上是{{ 1}}对,然后孩子(func, args)完成任务。 get实际上是通过调用Queue然后将结果写入管道或其他进程间通信机制来工作的。