在Python中同时执行两个类方法

Phy*_*ist 9 python multiprocessing python-multithreading python-3.x python-multiprocessing

我相信之前已经提出过许多类似的问题,但在阅读了很多类似的问题后,我仍然不太确定应该做些什么.所以,我有一个Python脚本来控制一些外部仪器(摄像头和功率计).我通过使用ctypes调用.dll文件中的C函数为两种乐器编写了类.现在它看起来像这样:

for i in range(10):
    power_reading = newport.get_reading(N=100,interval=1) # take power meter reading
    img = camera.capture(N=10)
    value = image_processing(img) # analyze the img (ndarray) to get some values
    results.append([power_reading,value]) # add both results to a list
Run Code Online (Sandbox Code Playgroud)

我想同时开始执行前两行.双方newport.get_readingcamera.capture需要100ms-1运行(他们会在同一时间运行,如果我选择了正确的参数).我不需要它们在同一时间完全启动,但理想情况下延迟应该小于总运行时间的大约10-20%(因此当每次运行时运行时间小于0.2秒).根据我的阅读,我可以使用该multiprocessing模块.所以我根据这篇文章尝试这样的事情:

def p_get_reading(newport,N,interval,return_dict):
    reading = newport.get_reading(N,interval,return_dict)
    return_dict['power_meter'] = reading

def p_capture(camera,N,return_dict):
    img = camera.capture(N)
    return_dict['image'] = img

for i in range(10):
    manager = multiprocessing.Manager()
    return_dict = manager.dict()
    p = multiprocessing.Process(target=p_capture, args=(camera,10))
    p.start()
    p2 = multiprocessing.Process(target=p_get_reading, args=(newport,100,1))
    p2.start()
    p.join()
    p2.join()
    print(return_dict)
Run Code Online (Sandbox Code Playgroud)

我有一些问题/疑问:

  1. 我需要从两个函数调用中获取返回值.使用我当前的方法,return_dict只显示输入capture_img但不显示功率计读数,为什么?它还读到我可以使用Queue,目前最好的方法是什么?

  2. 我怎么知道这两个函数是否确实同时开始运行?我正在考虑使用该time模块记录两个函数的开始和结束时间,也许使用一些包装函数来进行时间记录,但是会使用multiprocessingpose任何限制吗?

  3. 我通常在IDE(spyder)上运行我的代码,根据我的阅读,我需要在命令提示符下运行以查看输出(我在函数内部有一些打印语句用于调试目的).我是否仍然可以在IDE中运行以同时运行这两个功能?

qua*_*ana 3

使用 aLock可能有助于同步:

import multiprocessing

def p_get_reading(newport, N, interval, lock, return_dict):
    lock.acquire()
    lock.release()
    reading = newport.get_reading(N, interval)
    return_dict['power_meter'] = reading

def p_capture(camera, N, lock, return_dict):
    lock.acquire()
    lock.release()
    img = camera.capture(N)
    return_dict['image'] = img

if __name__ == "__main__":    
    for i in range(10):
        manager = multiprocessing.Manager()
        return_dict = manager.dict()
        lock = multiprocessing.Lock()
        lock.acquire()
        p = multiprocessing.Process(target=p_capture, args=(camera,10,lock,return_dict))
        p.start()
        p2 = multiprocessing.Process(target=p_get_reading, args=(newport,100,1,lock,return_dict))
        p2.start()
        lock.release()
        p.join()
        p2.join()
        print(return_dict)
Run Code Online (Sandbox Code Playgroud)

Process现在可以按任意顺序创建和编辑这两个对象start(),因为主例程已经获取了锁。一旦释放,两个进程将相互争斗以获取和释放锁,并且几乎同时准备好。

另外,请注意使用,if __name__ == "__main__"因为这有助于multiprocessing创建新流程。

我必须说这似乎是对Lock