我的进程完成了其“运行”功能,但没有消失

时间:2019-09-04 01:17:24

标签: python python-multiprocessing

我正在对multiprocessing.Process进行子类化,以创建一个类,该类将从照相机中异步获取图像,并将其推送到一些队列中进行显示并保存到磁盘。

我遇到的问题是,当我使用属于Process-descendant-object的multiprocessing.Event对象发出停止命令时,该过程成功完成了run函数的最后一行,但然后它就不会消失。该过程只是继续存在,并继续从is_alive函数返回true。我不知道这怎么可能。是什么导致进程完成其run功能但不死?

更有趣的是,当我将该对象与在其中使用它的较大上下文分离时(包括同时运行的其他多个Process子类),我无法重现该问题,这往往使我认为它具有某些优点处理其余的代码,但我不知道怎么回事-如果它执行了run函数的最后一行,那么不管发生了什么,它是否都会死掉?我一定对Process对象的工作方式有误解。

这是下面的代码。运行它时,我看到消息“视频获取停止的进程”,但该进程没有消失。

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()

感谢您的帮助。

0 个答案:

没有答案