gpt4 book ai didi

python picamera,键盘 ctrl+c/sigint 未捕获

转载 作者:太空宇宙 更新时间:2023-11-03 14:38:27 25 4
gpt4 key购买 nike

来自 pycamera docs我以快速捕获和处理为例,并添加了一个 sigint 事件处理程序来捕获键盘中断:

import io
import time
import threading
import picamera

# Create a pool of image processors
done = False
lock = threading.Lock()
pool = []

def signal_handler(signal, frame):
global done
print 'You pressed Ctrl+C!'
done=True
sys.exit()

signal.signal(signal.SIGINT, signal_handler)
class ImageProcessor(threading.Thread):
def __init__(self):
super(ImageProcessor, self).__init__()
self.stream = io.BytesIO()
self.event = threading.Event()
self.terminated = False
self.daemon=True;
self.start()

def run(self):
# This method runs in a separate thread
global done
while not self.terminated:
# Wait for an image to be written to the stream
if self.event.wait(1):
try:
self.stream.seek(0)
# Read the image and do some processing on it
#Image.open(self.stream)
#...
#...
# Set done to True if you want the script to terminate
# at some point
#done=True
finally:
# Reset the stream and event
self.stream.seek(0)
self.stream.truncate()
self.event.clear()
# Return ourselves to the pool
with lock:
pool.append(self)

def streams():
while not done:
with lock:
if pool:
processor = pool.pop()
else:
processor = None
if processor:
yield processor.stream
processor.event.set()
else:
# When the pool is starved, wait a while for it to refill
time.sleep(0.1)

with picamera.PiCamera() as camera:
pool = [ImageProcessor() for i in range(4)]
camera.resolution = (640, 480)
camera.framerate = 30
camera.start_preview()
time.sleep(2)
camera.capture_sequence(streams(), use_video_port=True)

# Shut down the processors in an orderly fashion
while pool:
with lock:
processor = pool.pop()
processor.terminated = True
processor.join()

但是中断信号永远不会被捕获。

直到camera.capture_sequence(streams(), use_video_port=True)运行信号被捕获,capture_sequence启动后信号处理程序不会被调用。

我是Python新手,所以也许答案很简单。我在这里做错了什么?

编辑:

如果我删除以下代码,信号就会被捕获:

 yield processor.stream

最佳答案

问题在于您正在使用thread.join(),它会阻塞主线程,这意味着您的程序必须等到您加入的线程完成才能继续。

信号总是会被主进程捕获,因为它是接收信号的进程,它是拥有线程的进程。

关于如何处理主线程和 CTRL+C 有很多答案,我给你三个选择,

首先,为 join() 调用添加超时:

thread1.join(60) 详细信息 here

其次,启动一个新进程来处理杀死程序的信号。

class Watcher():  

def __init__(self):
self.child = os.fork()
if self.child == 0:
return
else:
self.watch()

def watch(self):
try:
os.wait()
except KeyboardInterrupt:
self.kill()
sys.exit()

def kill(self):
try:
os.kill(self.child, signal.SIGKILL)
except OSError:
pass

在开始工作线程之前启动一个观察者,例如

def main():  
init()
Watcher()
start_your_thread1()
start_your_thread2()
start_your_thread3()

最终的、你原来的方式、复杂的生产者和消费者方式。

只需删除最后的 join(),为主线程添加一些任务即可。

我更喜欢第二个选项,它很容易使用,并解决了 Python 中多线程程序的两个问题,(1) 信号可能会传递到任何线程(这只是一个缺陷),(2) 如果线程得到信号正在等待,信号被忽略(这是一个错误)。有关观察者的更多详细信息请参阅本书的附录 A The Little Book of Semaphores

关于python picamera,键盘 ctrl+c/sigint 未捕获,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46734703/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com