Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/313.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 我的进程完成了它的“run”功能,但它没有';别死_Python_Python Multiprocessing - Fatal编程技术网

Python 我的进程完成了它的“run”功能,但它没有';别死

Python 我的进程完成了它的“run”功能,但它没有';别死,python,python-multiprocessing,Python,Python Multiprocessing,我正在子类化多处理。Process以创建一个类,该类将异步地从相机抓取图像,并将其推送到一些队列中以显示和保存到磁盘 我遇到的问题是,当我使用属于进程子体对象的多处理.Event对象发出停止命令时,进程成功地完成了run函数的最后一行,但之后它不会死。该进程只是继续存在,并继续从is\u alive函数返回true。我不明白这怎么可能。什么会导致进程完成其运行功能而不死亡 令人发狂的是,当我将这个对象与我正在使用它的更大的上下文(其中包括几个同时运行的其他流程子类)分离时,我无法重现这个问题,这

我正在子类化
多处理。Process
以创建一个类,该类将异步地从相机抓取图像,并将其推送到一些队列中以显示和保存到磁盘

我遇到的问题是,当我使用属于进程子体对象的
多处理.Event
对象发出停止命令时,进程成功地完成了
run
函数的最后一行,但之后它不会死。该进程只是继续存在,并继续从
is\u alive
函数返回true。我不明白这怎么可能。什么会导致进程完成其
运行
功能而不死亡

令人发狂的是,当我将这个对象与我正在使用它的更大的上下文(其中包括几个同时运行的其他流程子类)分离时,我无法重现这个问题,这往往会让我认为它与代码的其余部分有关,但我不明白这是怎么回事——如果它执行了
run
函数的最后一行,那么不管发生了什么,它不应该死掉吗?我一定是误解了进程对象的工作原理

下面是代码。当我运行它时,我看到消息“Video acquires process STOPPED”(视频采集进程已停止)打印出来,但进程并没有停止

class VideoAcquirer(mp.Process):
    def __init__(self, camSerial, imageQueue, monitorImageQueue, acquireSettings={}, monitorFrameRate=15):
        mp.Process.__init__(self, daemon=True)
        self.camSerial = camSerial
        self.acquireSettings = acquireSettings
        self.imageQueue = imageQueue
        self.monitorImageQueue = monitorImageQueue
        self.videoFrequencyEntry.get()Rate = monitorFrameRate
        self.stop = mp.Event()

    def stopProcess(self):
        print('Stopping video acquire process')
        self.stop.set()

    def run(self):
        system = PySpin.System.GetInstance()
        camList = system.GetCameras()
        cam = camList.GetBySerial(self.camSerial)
        cam.Init()
        nodemap = cam.GetNodeMap()
        setCameraAttributes(nodemap, self.acquireSettings)
        cam.BeginAcquisition()

        monitorFramePeriod = 1.0/self.monitorFrameRate
        print("Video monitor frame period:", monitorFramePeriod)
        lastTime = time.time()
        k = 0
        im = imp = imageResult = None
        print("Image acquisition begins now!")
        while not self.stop.is_set():
            try:
                #  Retrieve next received image
                print(1)
                imageResult = cam.GetNextImage(100) # Timeout of 100 ms to allow for stopping process
                print(2)
                #  Ensure image completion
                if imageResult.IsIncomplete():
                    print('Image incomplete with image status %d...' % imageResult.GetImageStatus())
                else:
                    #  Print image information; height and width recorded in pixels
                    width = imageResult.GetWidth()
                    height = imageResult.GetHeight()
                    k = k + 1
                    print('Grabbed Image %d, width = %d, height = %d' % (k, width, height))
                    im = imageResult.Convert(PySpin.PixelFormat_Mono8, PySpin.HQ_LINEAR)
                    imp = PickleableImage(im.GetWidth(), im.GetHeight(), 0, 0, im.GetPixelFormat(), im.GetData())
                    self.imageQueue.put(imp)

                    # Put the occasional image in the monitor queue for the UI
                    thisTime = time.time()
                    if (thisTime - lastTime) >= monitorFramePeriod:
                        # print("Sent frame for monitoring")
                        self.monitorImageQueue.put((self.camSerial, imp))
                        lastTime = thisTime

                    imageResult.Release()
                print(3)
            except PySpin.SpinnakerException as ex:
                pass # Hopefully this is just because there was no image in camera buffer
                # print('Error: %s' % ex)
                # traceback.print_exc()
                # return False

        # Send stop signal to write process
        print(4)
        self.imageQueue.put(None)

        camList.Clear()
        cam.EndAcquisition()
        cam.DeInit()
        print(5)
        del cam
        system.ReleaseInstance()
        del nodemap
        del imageResult
        del im
        del imp
        del camList
        del system
        print("Video acquire process STOPPED")
我从tkinter GUI线程开始这个过程,大致如下:

import multiprocessing as mp
camSerial = '2318921'
queue = mp.Queue()
videoMonitorQueue = mp.Queue()
acquireSettings = [('AcquisitionMode', 'Continuous'), ('TriggerMode', 'Off'), ('TriggerSource', 'Line0'), ('TriggerMode', 'On')]

v = VideoAcquirer(camSerial, queue, videoMonitorQueue, acquireSettings=acquireSettings, monitorFrameRate=15)
下面是我如何停止进程的大致方式,也是从tkinter GUI线程:

v.stopProcess()

感谢您的帮助。

也许向我们展示如何在您的实际环境中使用它会有所帮助。在流程中附加一个调试器,以了解它应该停止时实际在做什么,怎么样?您是否必须在流程正确完成之前加入该流程?@Sraw我同意这会很有用,但其余的代码相当大。通常我会发布一个最小的工作(或非工作)示例,但在这种情况下,当我试图隔离这个类时,我无法重现错误@DanielJunglas听起来很有用-我从来没有这样做过,但我会研究一下,谢谢。让我们看看你如何称呼这个过程?