KeyboardInterrupt不能在Python中停止线程



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

调用一个函数如果<<blockquote>strong>名称主要= =,":

,但它不工作。我在蟒蛇环境中使用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)

如果我以这样的方式改变程序,keyboardInterrupt调用没有任何函数,那么它工作

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脚本调用,然后它就可以工作了。任何理由吗?

任何想法?它是如何工作的?

...
print ('Press CTRL-C to interrupt')
try: 
while grabber.isAlive():
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() 
...

试试这个方法。KeyboardInterrupt不工作的原因是因为while循环的作用域是try except语句,所以即使你按下了KeyboardInterrupt,它也会不断地重复它。

希望这对你有帮助!

相关内容

  • 没有找到相关文章

最新更新