首页 > 解决方案 > 在两个进程之间交换值?

问题描述

我有一个为在我的树莓派上运行的 python 2.7 编写的 python 脚本。我试图做的是用我的步进电机向前移动,同时检查前面是否有一个正方形。为了不干扰这些事情,我想将图像处理移动到它自己的进程中,并在采取进一步步骤之前检查是否找到了图像。

这些是涉及的类。

SharedImageDetectionValue

class SharedImageDetectionValue(object):
    stored_has_position_found = False

    def get_has_position_found(self):
        return self.stored_has_position_found

    def set_has_position_found(self, new_value):
        self.stored_has_position_found = new_value
        return self.stored_has_position_found

ImageProcessor

class ImageProcessor:
    def __init__(self):
        # constructor code

    def run(self, shared):
        # do image processing till found a square
        shared.set_has_position_found(True)

Stepper

class Stepper(Observable):
    def __init__(self):
        # constructor code

    def run_until_stopped(self, shared):
        # some motor code
        while self.running:
            has_found = shared.get_has_position_found()
            print("[ StepperH ] Value has found: " + str(has_found))
            if not has_found:
                self.do_steps(0.0005)

进程管理器:

class ProcessManager(BaseManager):
    pass

我尝试用它来创建这个过程:

ProcessManager.register('SharedImageDetectionValue', SharedImageDetectionValue)
manager = ProcessManager()
manager.start()

shared = manager.SharedImageDetectionValue()
pool = Pool(1)

imgProcessor = ImageProcessor()
pool.apply_async(imgProcessor.run, args=(shared, ))

print("[ MAIN ] StepperH add to pool")
Stepper().run_until_stopped(shared)

出于测试目的,我在图像处理器中直接将值设置为 true,但在步进器中它保持为 False。我也尝试将其添加Stepper到池中,但似乎步进器也没有运行。

我还尝试通过两个辅助函数调用进程,但效果相似:

def start_processing(passed_shared):
    ImageProcessor().run(passed_shared)

def start_moving_to_target_platform(passed_shared):
    StepperH().run_until_stopped(passed_shared)

我究竟做错了什么?

标签: pythonpython-2.7ipcpython-multiprocessing

解决方案


当您只想共享一个值时,为什么要使用自定义管理器使事情复杂化 - 并且multiprocessing.Value正是为此而存在。此外,如果您只想使用它来运行单个进程,那么创建进程池是没有意义的。

您可以将代码大大简化为:

import ctypes
import multiprocessing

class ImageProcessor(multiprocessing.Process):

    def __init__(self, shared):
        super(ImageProcessor, self).__init__()
        self.shared = shared

    def run(self):
        # do image processing till found a square
        self.shared.value = True

class Stepper(Observable):

    def run_until_stopped(self, shared):
        while self.running:
            print("[ StepperH ] Value has found: {}".format(shared.value)
            if not shared.value:
                self.do_steps(0.0005)

    # rest of your Stepper code

if __name__ == "__main__":  # a multiprocessing guard
    shared = multiprocessing.Value(ctypes.c_bool, False)

    img_processor = ImageProcessor(shared)
    img_processor.start()

    Stepper().run_until_stopped(shared)

在不牺牲任何现有功能的情况下。


推荐阅读