提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
注意下面
如果有车载讨论需要的小伙伴,可以私信加我微信
,拉你进群,和同行业大佬交流
注意上面
前言
最近忙着搞项目的事情,碰到关于协程的问题,今天实践完以后浅浅的记录一下,防止自己以后忘记了
提示:以下是本篇文章正文内容,下面案例可供参考
一、实践源码
import asyncio
import time
import serial
from typing import Optional
from queue import Queue
class SerialControl:
def __init__(self):
self.__control_flag = 0
self.__check_flag = False
self.__ser = None
self.__q = Queue(5)
@property
def check_flag(self):
return self.__check_flag
def ser_init(self, ser_num: Optional[str]):
"""初始化串口对象函数"""
try:
self.__ser = serial.Serial(ser_num, 115200)
return self.__ser
except Exception:
return self.__ser
def flush_input(self):
"""清空输入缓存区"""
self.__ser.flushInput()
def flush_output(self):
"""清空输出缓存区"""
self.__ser.flushOutput()
def open(self):
"""开启串口"""
if self.__ser is not None:
if self.__ser.isOpen() is False:
self.__ser.open()
def close(self):
"""关闭串口"""
if self.__ser is not None:
if self.__ser.isOpen() is True:
self.__ser.close()
def send(self, data: Optional[str]):
"""
通过串口发送数据
param1:字符串类型数据,需要发送得数据,str
"""
send_data = "{}\r\n".format(data).encode("UTF-8")
self.__ser.write(send_data)
async def __get_fish_state(self,check_input,check_num,check_interval):
self.send(check_input)
time_flag = 0
while time_flag < check_num:
await asyncio.sleep(check_interval)
if self.__check_flag is True:
return True
time_flag += 1
return False
async def __recv(self, check_text: Optional[str], check_num: Optional[int],
check_interval: Optional[float]):
"""
通过串口检测接受到得数据
param1:需要检测得数据,str
param2:串口输入参数,str
param3:循环检测次数,int
param4:循环检查时间间隔,float
"""
self.__ser.flushInput()
self.__check_flag = False
time_flag = 0
data = ""
while time_flag < check_num: # 超时函数1.5s
await asyncio.sleep(check_interval)
if self.__ser.inWaiting() > 0:
recv_text = (self.__ser.read(self.__ser.inWaiting()))
data += (recv_text.decode("utf-8", "ignore")).strip() # 持续接收数据
if check_text in data:
self.__check_flag = True
break
time_flag += 1
def check_states(self,check_text,check_input,check_num,check_interval):
loop = asyncio.new_event_loop() # 创建一个协程循环对象
asyncio.set_event_loop(loop) # 设置这个对象为循环事件
recv_task = loop.create_task(self.__recv(check_text,check_num,check_interval)) # 创建一个接收窗口的循环任务
get_states_task = loop.create_task(self.__get_fish_state(check_input,check_num,check_interval)) # 创建一个发送信息并检测结果的循环任务
task = [recv_task,get_states_task] # 将循环任务放进循环列表中
loop.run_until_complete(asyncio.wait(task)) # 运行这个循环事件对象
return get_states_task.result()
if __name__ == '__main__':
my_ser = SerialControl()
my_ser.ser_init('COM37')
print(time.time())
state = my_ser.check_states("input data",'check text',15,0.05)
print(state)
print(time.time())
二、使用协程的两个函数
1.串口接收函数
代码如下(示例):
async def __recv(self, check_text: Optional[str], check_num: Optional[int],
check_interval: Optional[float]):
"""
通过串口检测接受到得数据
param1:需要检测得数据,str
param2:串口输入参数,str
param3:循环检测次数,int
param4:循环检查时间间隔,float
"""
self.__ser.flushInput()
self.__check_flag = False
time_flag = 0
data = ""
while time_flag < check_num: # 超时函数1.5s
await asyncio.sleep(check_interval)
if self.__ser.inWaiting() > 0:
recv_text = (self.__ser.read(self.__ser.inWaiting()))
data += (recv_text.decode("utf-8", "ignore")).strip() # 持续接收数据
if check_text in data:
self.__check_flag = True
break
time_flag += 1
2.检测返回状态的函数
代码如下(示例):
async def __get_fish_state(self,check_input,check_num,check_interval):
self.send(check_input)
time_flag = 0
while time_flag < check_num:
await asyncio.sleep(check_interval)
if self.__check_flag is True:
return True
time_flag += 1
return False
其实这里async的意思是标识它是一个协程函数,await在这期间去执行其他的任务
3.封装多个协程函数进入循环事件运行函数
def check_states(self,check_text,check_input,check_num,check_interval):
loop = asyncio.new_event_loop() # 创建一个协程循环对象
asyncio.set_event_loop(loop) # 设置这个对象为循环事件
recv_task = loop.create_task(self.__recv(check_text,check_num,check_interval)) # 创建一个接收窗口的循环任务
get_states_task = loop.create_task(self.__get_fish_state(check_input,check_num,check_interval)) # 创建一个发送信息并检测结果的循环任务
task = [recv_task,get_states_task] # 将循环任务放进循环列表中
loop.run_until_complete(asyncio.wait(task)) # 运行这个循环事件对象
return get_states_task.result() # 获取返回状态函数的返回值
这里将两个协程函数创建成两个任务放进循环事件中执行,当两个函数碰到await修饰符时就会去执行下一个协程函数,简单测试了一下和创建两个线程去操作时间上并不会有太大的差别
写在结尾
我是一名车载集成测试开发工程师,希望能和志同道合的朋友一起相互学习进步