悲情"Error has occured during the function import"

Pathos "Error has occured during the function import"

当我尝试执行这段代码时:

import pathos
from network import *


def simulation(error_rate=1):
    network = Network(error_rate=1)
    network.gen_transceiver_pair(1)
    network.run()
    mend = network.master_transceivers[0].cycle[0, 2]
    send = network.slave_transceivers[0].cycle[0, 2]
    return send if send > mend else mend

if __name__ == '__main__':
    p = pathos.pools.ParallelPool(nodes=10)
    result = p.map(simulation, [1, 1, 1])

我收到这个错误:

An error has occured during the function import
Traceback (most recent call last):
  File "C:\Users\user\PycharmProjects\network_simu\venv\lib\site-packages\ppft\__main__.py", line 100, in run
    six.exec_(__fobj)
  File "<string>", line 1, in <module>
  File "<string>", line 6, in Network
NameError: name 'signal' is not defined
A fatal error has occured during the function execution
Traceback (most recent call last):
  File "C:\Users\user\PycharmProjects\network_simu\venv\lib\site-packages\ppft\__main__.py", line 109, in run
    __f = locals()[ppc.str_(__fname)]
KeyError: 'simulation'

是不是因为我在函数内部生成了一个Network对象?理想情况下,我想 运行 以不同的错误率(1、.9 等)模拟 10^6-10^7 次。我尝试使用 multiprocessing 运行 但无法 pickle 函数,因此我尝试使用 Pathos.

编辑:我正在使用 blinker 模块中的 signal。代码在正常执行时工作。我已经完成了 10^6 次迭代,没有任何问题,但它需要很长时间。

编辑2: 我这样使用信号:

class Pool:
    def __init__(self):
        Transceiver.pool_add.connect(self.add)
        Transceiver.pool_remove.connect(self.remove)
        Network.return_cycle.connect(self.set_cycle)
        self.cycle = 0
        self.pool = []

    def set_cycle(self, sender):
        self.cycle = sender.cycle

    def add(self, sender):
        if VERBATIM:
            print("added " + sender.t_id)
        self.pool.insert(0, sender)
        sender.cycle[0, 0] = self.cycle

    def remove(self, sender):
        if VERBATIM:
            print("removed " + sender.t_id)
        self.pool.remove(sender)
        sender.cycle[0, 2] = self.cycle

class Transceiver(NetworkComponent):
    __STATUS = ["off", "t_on", "r_on", "on"]
    pool_add = signal("pool_add")
    pool_remove = signal("pool_remove")
    __ID = iter(range(1, 41))

Edit3:所以我删除了 signal 的使用。现在我得到这个错误:

Backend TkAgg is interactive backend. Turning interactive mode on.
An error has occured during the function import
Traceback (most recent call last):
  File "C:\Users\user\PycharmProjects\network_simu\venv\lib\site-packages\ppft\__main__.py", line 100, in run
    six.exec_(__fobj)
  File "<string>", line 1, in <module>
  File "<string>", line 7, in Network
NameError: name 'np' is not defined
A fatal error has occured during the function execution

npnumpy... 很奇怪

我是 pathos 的作者。首先,您正在使用 ParallelPool,它使用 ppft... 它使用 dill.source 将对象转换为源代码,然后将源代码传递给新进程以进行构建一个新对象并执行。您可能想尝试 ProcessPool,它使用 multiprocess,它使用 dill,它使用更标准的对象序列化(如 pickle)。此外,当您序列化代码时(使用 dilldill.source),您应该注意确保代码尽可能自封装。我的意思是:

def sin2(x):
    import numpy as np
    return np.sin(x)**2

更有机会序列化
import numpy as np

def sin2(x):
    return np.sin(x)**2

因为后者依赖于序列化程序来追踪 sin2 中所有未定义的项目。因此,只需将所有导入添加到您打算并行使用的任何函数中,就可以使其更有可能工作。 (请注意,以上两者都应该有效,但前者在序列化器上比后者更容易。)对于函数和在要序列化的对象的名称空间内使用的任何其他对象,实际上也是如此,但是通过引用查找在封闭的命名空间中找到。像这样考虑:序列化程序保证提供您要定位的任何功能......并且实质上将其传输到另一个处理器并执行该代码。如果还需要一个参考查找,但没有复制过来……那么它将失败。因此,通过简化包含要发布的代码的命名空间层次结构并减少要发布的代码之外的依赖项数量,帮助它不会失败。