Python使用进程间共享变量来控制两个进程(监听键盘和相机录制)
我有个简单的应用需求: 1. 该应用随时会监听键盘的输入; 2. 当输入指定键时会控制相机录制的启动和关闭。 监听键盘是一个事件循环,相机录制也是一个循环录制的过程。我试着用 Python 启动两个进程,并用两个进程共享变量的更新来控制两个进程的交互。 监听键盘输入首先我找到python 监听键盘输入的方案可以满足我监听键盘的需求。 1 import sys,select,tty,termios 2 3 old_attr = termios.tcgetattr(sys.stdin) 4 tty.setcbreak(sys.stdin.fileno()) 5 print('Please input keys,press Ctrl + C to quit') 6 7 while(1): 8 if select.select([sys.stdin],[],0)[0] == [sys.stdin]: 9 print(sys.stdin.read(1)) 10 11 termios.tcsetattr(sys.stdin,termios.TCSADRAIN,old_attr) 这段代码可以进行键盘监听,但是却有一个潜在 Bug:第 11 行的代码永远无法执行,即使加上跳出循环的判断,当使用 Ctrl+C 时程序会终止。 而第 11 行的作用是恢复当前终端的原始属性,没执行到该语句,终端会变得不正常:你会发现程序结束后在该终端输入字符不会有显示。因此,程序应该设法程序终止时必然执行该语句。 我建议改为类似的代码来修复这个 Bug: sys 2 select 3 tty termios 5 6 old_attr = termios.tcgetattr(sys.stdin) tty.setcbreak(sys.stdin.fileno()) 8 9 10 try: 11 while True: 12 13 key = sys.stdin.read(114 if key == q15 # to stop the infinite loop 16 break 17 elif key == s18 do something 19 I will do something20 else21 do other things 22 print(key) 23 24 except Exception as e: 25 (e) 26 finally27 termios.tcsetattr(sys.stdin,old_attr) 相机录制相机录制的路径当然因不同的相机而异,因此这里我只写 Demo 级别的抽象代码: time 3 class Recorder: 5 def __init__(self): 6 Recorder initialization. 7 def run(self): 9 time.sleep(0.310 Recording a frame.11 12 close(self): 13 Recording ended.14 15 16 recorder = Recorder() 17 18 t0 = time.time() 19 while time.time() - t0 < 1020 recorder.run() 21 22 recorder.close() 可以看到这段逻辑也有一个条件循环。 假设应用的需求是按键 s,进行录制;再次按键 s,终止录制。 由于这两个逻辑需要完全同时进行,而 Python 的线程又是伪并行,因此这里考虑用多进程共享变量的通信。 使用进程间共享变量使用 multiprocessing,直接看完整的代码是比较直观的: 6 multiprocessing 8 9 10 11 12 13 14 time.sleep(0.315 16 17 18 19 20 21 recording_process(shared): 22 recorder =23 while shared[is_recording]: recorder.run() 25 recorder.close() 27 28 29 if __name__ == __main__30 set shared variable 31 manager = multiprocessing.Manager() 32 shared = manager.dict() 33 shared['] = False 34 35 old_attr =36 tty.setcbreak(sys.stdin.fileno()) 37 38 39 check the keyborad 40 p = None 41 42 43 44 key = sys.stdin.read(145 46 47 48 49 toggle 50 shared['] = not shared[] 51 resume or stop recording 52 if shared[53 p = multiprocessing.Process(target=recording_process,args=(shared,)) 54 p.start() 55 56 p and p.join() 57 58 59 60 61 62 63 64 termios.tcsetattr(sys.stdin,old_attr) ? 原文作者:雨先生 参考
(编辑:北几岛) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |