KeyboardInterrupt 在 Python 中不起作用以停止线程

如何解决KeyboardInterrupt 在 Python 中不起作用以停止线程

我想使用两个线程从实时流中捕获和存储图像。我想用 Ctrl + C 键盘中断来停止线程。我正在从

调用一个函数

if name == "ma​​in":

但它不起作用。我在 anaconda 环境中使用 spyder。我也使用终端尝试过,但它不起作用。任何人都可以解释为什么以及如何工作?

代码如下

class ImageGrabber(threading.Thread):
def __init__(self,ID):
    threading.Thread.__init__(self)
    self.ID=ID
    self.cam=cv2.VideoCapture(ID)
    self.fps = self.cam.get(cv2.CAP_PROP_FPS)
    self.w=self.cam.get(cv2.CAP_PROP_FRAME_WIDTH)
    self.h=self.cam.get(cv2.CAP_PROP_FRAME_HEIGHT)
    (self.grabbed,self.frame) =self.cam.read()
    print(f"Camera Opened with fps {self.fps},width = {self.w},and height = {self.h}")
    plt.imshow(self.frame)
    plt.show()
    self.stopped = False
    
def run(self):
    global frames
    global exitProgram
    # print("Entered Grabbed Run ******:")
    while not self.stopped:
        if not self.grabbed or exitProgram is True:
            print("Exit Command reached")
            self.stop()
            self.cam.release()
        else:
            (self.grabbed,self.frame) =self.cam.read()
            frames.put(self.frame)
            
def stop(self):
    self.stopped = True

class ImageSaver(threading.Thread):
def __init__(self,grabber,codec):
     
    threading.Thread.__init__(self)
    global saveImages
    fourcc = cv2.VideoWriter_fourcc(*codec)
    self.fName=self.getDateStamp() + '.avi'
    if saveImages is False:
        self.out = cv2.VideoWriter(self.fName,fourcc,grabber.fps,(int(grabber.w),int(grabber.h)))
    
def getDateStamp(self):

    filedate = str(datetime.Now())
    filedate = filedate[0:-7]
    filedate = filedate.replace(':','_')
    filename = filedate 
#print(filename)

    return filename
def run(self):
    global frames
    global saveImages
    while True:
        # print("Entered Loop 1:")
        if(not frames.empty()):
            # print("Entered frame showing:")
            self.Currframe=frames.get()
            if saveImages is False:
                self.out.write(self.Currframe)
            else:
                self.imgName=self.getDateStamp() + '.tiff'
                cv2.imwrite(self.imgName,self.Currframe)
            print(f"Queue Size in writing = {frames.qsize()}")
            # print("Show Image")
        elif exitProgram is True:
            print("Exit Command Main reached")
            print(f"Final Queue Size at exit = {frames.qsize()}")
            break

def initStart(*args):

    argsList=sum(list(args),[])
    argsLen = len(argsList)

    if(argsLen==2):
        ID = int(argsList[0])
        codec = argsList[1]
    elif(argsLen==1):
        ID = int(argsList[0])
        codec = 'XVID'
    else:
        ID = 0
        codec = 'XVID'
    
    grabber = ImageGrabber(ID)
    saver = ImageSaver(grabber,codec)

    grabber.start()
    saver.start()
    e = threading.Event()
    # main.join()
    # grabber.join()

    print ('Press CTRL-C to interrupt')
    while grabber.isAlive():
        try: 
            time.sleep(1) #wait 1 second,then go back and ask if thread is still alive
            print ('Sleep...')
        except: #if ctrl-C is pressed within that second,#catch the KeyboardInterrupt exception
                
            e.set() #set the flag that will kill the thread when it has finished
            exitProgram=True
            print ('Exiting...')
            grabber.join()
            saver.join()

if __name__ == "__main__":
    full_cmd_arguments = sys.argv
    # Keep all but the first. First contains the path of script or file
    argument_list = full_cmd_arguments[1:]
    initStart(argument_list)

如果我以这样一种方式更改程序,即在没有任何功能的情况下调用键盘中断,那么它就可以工作

grabber = ImageGrabber(0)
main = Main(grabber,'XVID')

grabber.start()
main.start()
e = threading.Event()
print ('Press CTRL-C to interrupt')
while grabber.isAlive():
    try: time.sleep(1) #wait 1 second,then go back and ask if thread is 
 
    except KeyboardInterrupt: #if ctrl-C is pressed within that second,#catch the KeyboardInterrupt exception
            
        e.set() #set the flag that will kill the thread when it has finished
        exitProgram=True
        print ('Exiting...')
        grabber.join()
        main.join()

上面的代码直接作为python脚本调用就可以了。有什么理由吗?

有什么想法吗?它是如何工作的?

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?
Java在半透明框架/面板/组件上重新绘画。
Java“ Class.forName()”和“ Class.forName()。newInstance()”之间有什么区别?
在此环境中不提供编译器。也许是在JRE而不是JDK上运行?
Java用相同的方法在一个类中实现两个接口。哪种接口方法被覆盖?
Java 什么是Runtime.getRuntime()。totalMemory()和freeMemory()?
java.library.path中的java.lang.UnsatisfiedLinkError否*****。dll
JavaFX“位置是必需的。” 即使在同一包装中
Java 导入两个具有相同名称的类。怎么处理?
Java 是否应该在HttpServletResponse.getOutputStream()/。getWriter()上调用.close()?
Java RegEx元字符(。)和普通点?