【发布时间】:2018-07-26 07:07:24
【问题描述】:
我想同时控制和运行两台实验室设备(至少同时启动它们),所以我使用了多处理模块。
from myLabModule import Newport1936R
from myLabModule import DCx_camera
from multiprocessing import Process, Queue
def multiprocess_camera(camera, shots_per_img, queue, delay):
time.sleep(delay)
img, camera_time = camera.capture(shots_per_img, np.float64, True) #img is a 2x2 ndarray
results = [camera_time[0], camera_time[1], img, 'img']
queue.put(results)
def multiprocess_power(newport, interval, N, queue, delay):
time.sleep(delay)
power_reading, newport_time = newport.get_power(interval, N, True)
results = [newport_time[0], newport_time[1], power_reading, 'power']
queue.put(results)
if __name__ == "__main__":
thorcam = DCx_camera()
newport = Newport1936R()
queue = Queue()
p1 = Process(target=multiprocess_camera, args=(thorcam,10,queue,0))
p2 = Process(target=multiprocess_power, args=(newport,1,10,queue,0))
p1.start()
p2.start()
p1.join()
p2.join()
results = []
results.append(queue.get())
results.append(queue.get())
当我运行代码时,我收到以下错误:AttributeError: Can't pickle local object 'CDLL.__init__.<locals>._FuncPtr'。我读了这个post,似乎它与变量的范围有关(我将另一个模块中定义的两个类传递给函数,函数基本上运行类的方法)。我不确定究竟是哪个部分导致了问题。我应该如何修改代码以使其工作?
【问题讨论】:
-
为什么你必须创建实例然后转发它们只是为了使用转发参数调用它们的方法?看起来这就是问题所在,如果这不是严格要求,为什么不在函数中创建实例?
-
@ikac 抱歉,我不太明白你的意思。正如我所说,我最终想要实现的是同时执行
thorcam.capture()和newport.get_power()(使用多处理)并获取它们的返回值。我刚刚查看了一些相关的帖子,似乎制作一个单独的函数是这样做的方法,当然我对其他更好的方法持开放态度。 -
那么你为什么不在目标方法中创建实例呢?如果实际用例与此示例类似,则您没有代码引用实例
thorcam和newport波纹管进程已启动。 -
是指在当前脚本中定义
thorcam和newport吗?我可以这样做,唯一的问题是我为thorcam和newport编写的模块有几百行长,所以我认为如果我将它们保存为单独的文件看起来会更简洁。是否可以只用几行重新定义类并将实际代码引用到单独的文件中? -
我的意思是完全不用担心酸洗。在这里,当您将实例作为目标的参数传递时执行酸洗,例如
args=(thorcam,10,queue,0)。thorcam必须腌制,我不确定DCx_camera是如何实现的。
标签: python-3.x class multiprocessing pickle python-multiprocessing