Python使用进程间共享变量来控制两个进程(监听键盘和相机录制)的交互
我有个简单的应用需求:
1. 该应用随时会监听键盘的输入;
2. 当输入指定键时会控制相机录制的启动和关闭。
监听键盘是一个事件循环,相机录制也是一个循环录制的过程。我试着用 Python 启动两个进程,并用两个进程共享变量的更新来控制两个进程的交互。
监听键盘输入
首先我找到python 监听键盘输入的方案可以满足我监听键盘的需求。
import sys, select, tty, termios old_attr = termios.tcgetattr(sys.stdin)
tty.setcbreak(sys.stdin.fileno())
print('Please input keys, press Ctrl + C to quit') while(1):
if select.select([sys.stdin], [], [], 0)[0] == [sys.stdin]:
print(sys.stdin.read(1)) termios.tcsetattr(sys.stdin, termios.TCSADRAIN, old_attr)
这段代码可以进行键盘监听,但是却有一个潜在 Bug:第 11 行的代码永远无法执行,即使加上跳出循环的判断,当使用 Ctrl+C 时程序会终止。
而第 11 行的作用是恢复当前终端的原始属性,没执行到该语句,终端会变得不正常:你会发现程序结束后在该终端输入字符不会有显示。因此,程序应该设法程序终止时必然执行该语句。
我建议改为类似的代码来修复这个 Bug:
import sys
import select
import tty
import termios old_attr = termios.tcgetattr(sys.stdin)
tty.setcbreak(sys.stdin.fileno())
print('Please input keys, press Ctrl + C to quit') try:
while True:
if select.select([sys.stdin], [], [], 0)[0] == [sys.stdin]:
key = sys.stdin.read(1)
if key == 'q':
# to stop the infinite loop
break
elif key == 's':
# do something
print('I will do something')
else:
# do other things
print(key) except Exception as e:
print(e)
finally:
termios.tcsetattr(sys.stdin, termios.TCSADRAIN, old_attr)
相机录制
相机录制的路径当然因不同的相机而异,因此这里我只写 Demo 级别的抽象代码:
import time class Recorder:
def __init__(self):
print('Recorder initialization.') def run(self):
time.sleep(0.3)
print('Recording a frame.') def close(self):
print('Recording ended.') recorder = Recorder() t0 = time.time()
while time.time() - t0 < 10:
recorder.run() recorder.close()
可以看到这段逻辑也有一个条件循环。
假设应用的需求是按键 s,进行录制;再次按键 s,终止录制。
由于这两个逻辑需要完全同时进行,而 Python 的线程又是伪并行,因此这里考虑用多进程共享变量的通信。
使用进程间共享变量
使用 multiprocessing,直接看完整的代码是比较直观的:
import time
import sys
import select
import tty
import termios
import multiprocessing class Recorder:
def __init__(self):
print('Recorder initialization.') def run(self):
time.sleep(0.3)
print('Recording a frame.') def close(self):
print('Recording ended.') def recording_process(shared):
recorder = Recorder()
while shared['is_recording']:
recorder.run() recorder.close() if __name__ == '__main__':
# set shared variable
manager = multiprocessing.Manager()
shared = manager.dict()
shared['is_recording'] = False old_attr = termios.tcgetattr(sys.stdin)
tty.setcbreak(sys.stdin.fileno())
print('Please input keys, press Ctrl + C to quit') # check the keyborad
p = None
try:
while True:
if select.select([sys.stdin], [], [], 0)[0] == [sys.stdin]:
key = sys.stdin.read(1)
if key == 'q':
# to stop the infinite loop
break
elif key == 's':
# toggle
shared['is_recording'] = not shared['is_recording']
# resume or stop recording
if shared['is_recording']:
p = multiprocessing.Process(target=recording_process, args=(shared,))
p.start()
else:
p and p.join()
else:
# do other things
print(key) except Exception as e:
print(e)
finally:
termios.tcsetattr(sys.stdin, termios.TCSADRAIN, old_attr)
原文作者:雨先生
原文链接:https://www.cnblogs.com/noluye/p/11704982.html
许可协议:知识共享署名-非商业性使用 4.0 国际许可协议
参考
Python使用进程间共享变量来控制两个进程(监听键盘和相机录制)的交互的更多相关文章
- Python进阶----进程间数据隔离, join阻塞等待, 进程属性, 僵尸进程和孤儿进程, 守护进程
Python进阶----进程间数据隔离, join阻塞等待, 进程属性, 僵尸进程和孤儿进程, 守护进程 一丶获取进程以及父进程的pid 含义: 进程在内存中开启多个,操作系统如何区分这些进程, ...
- android 进程间通信 messenger 是什么 binder 跟 aidl 区别 intent 进程间 通讯? android 消息机制 进程间 android 进程间 可以用 handler么 messenger 与 handler 机制 messenger 机制 是不是 就是 handler 机制 或 , 是不是就是 消息机制 android messenge
韩梦飞沙 韩亚飞 313134555@qq.com yue31313 han_meng_fei_sha messenger 是什么 binder 跟 aidl 区别 intent 进程间 通讯 ...
- Python 进程间的通信
#-*-coding:utf-8-*- '''python提供了多种进程间的通信方式,如:Queue,Pipe,Valie+Array等. Queue与Pipe的区别在于Pipe常用来在两个进程间通信 ...
- Android查缺补漏(IPC篇)-- 进程间通讯基础知识热身
本文作者:CodingBlock 文章链接:http://www.cnblogs.com/codingblock/p/8479282.html 在Android中进程间通信是比较难的一部分,同时又非常 ...
- Python多进程编程-进程间协作(Queue、Lock、Semaphore、Event、Pipe)
进程与进程之间是相互独立的,互不干扰.如果多进程之间需要对同一资源操作,就需要进程间共享变量,上一篇文章介绍了进程间共享数据的三大类Value.Array.Manager,这三种类的主要区别在于管理的 ...
- Python之路(第三十九篇)管道、进程间数据共享Manager
一.管道 概念 管道可用于具有亲缘关系进程间的通信,有名管道克服了管道没有名字的限制,因此,除具有管道所具有的功能外,它还允许无亲缘关系进程间的通信. 先画一幅图帮助大家理解下管道的基本原理 现有2个 ...
- Python 多进程编程之 进程间的通信(在Pool中Queue)
Python 多进程编程之 进程间的通信(在Pool中Queue) 1,在进程池中进程间的通信,原理与普通进程之间一样,只是引用的方法不同,python对进程池通信有专用的方法 在Manager()中 ...
- python 使用多进程实现并发编程/使用queue进行进程间数据交换
import time import os import multiprocessing from multiprocessing import Queue, pool ""&qu ...
- Py修行路 python基础 (二十五)线程与进程
操作系统是用户和硬件沟通的桥梁 操作系统,位于底层硬件与应用软件之间的一层 工作方式:向下管理硬件,向上提供接口 操作系统进行切换操作: 把CPU的使用权切换给不同的进程. 1.出现IO操作 2.固定 ...
随机推荐
- [LeetCode] 375. Guess Number Higher or Lower II 猜数字大小之二
We are playing the Guess Game. The game is as follows: I pick a number from 1 to n. You have to gues ...
- [LeetCode] 72. Edit Distance 编辑距离
Given two words word1 and word2, find the minimum number of operations required to convert word1 to ...
- subprocess实用手册
背景 python执行操作系统的命令,如python执行shell命令 subprocess模块主要用于创建子进程,并连接它们的输入.输出和错误管道,获取它们的返回状态.通俗地说就是通过这个模块,你可 ...
- (九)golang--标识符的命名规则
标识符的概念: (1)各种变量.方法等命名时使用的字符序列被称为标识符: (2)凡是可以自己起名字的都可以叫标识符: 标识符的命名规则: (1)由26个英文字母大小写,0-9,_组成 (2)数字不可以 ...
- python面试题第一份
阅读目录 1 Python的函数参数传递 2 Python中的元类(metaclass) 3 @staticmethod和@classmethod 4 类变量和实例变量 5 Python自省 6 字典 ...
- linux ,查看端口
netstat -antlp | grep java 注:grep java是过滤所有java进程
- java 解决safari下载中文文件名乱码
主要就是在响应头设置content-disposition,主要遵循 RFC 5987标准. response.setHeader("content-disposition",&q ...
- 直接操作DOM一定比虚拟DOM操作耗时,diff算法,key值,虚拟 DOM的定义
直接操作DOM一定比虚拟DOM操作耗时吗? 或者一次直接DOM操作一定比一次虚拟DOM操作耗时吗? 1)虚拟DOM的本质就是一个JS对象,虚拟DOM减少了真实DOM的操作,当修改数据的时候,就是修改虚 ...
- 【Navicat】使用navicat执行sql 查询速度很慢解决方法
========================== Navicat 远程连接Mysql执行普通sql速度慢问题: 场景: navicat可以连接上 远程服务器的mysql.但是在navicat执行最 ...
- C# vb .NET识别读取QR二维码
二维码比条形码具有更多优势,有些场合使用二维码比较多,比如支付.那么如何在C#,.Net平台代码里读取二维码呢?答案是使用SharpBarcode! SharpBarcode是C#快速高效.准确的条形 ...