关于python 协程 async/await实践记录

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档


注意下面
如果有车载讨论需要的小伙伴,可以私信加我微信,拉你进群,和同行业大佬交流
注意上面

前言

最近忙着搞项目的事情,碰到关于协程的问题,今天实践完以后浅浅的记录一下,防止自己以后忘记了


提示:以下是本篇文章正文内容,下面案例可供参考

一、实践源码

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修饰符时就会去执行下一个协程函数,简单测试了一下和创建两个线程去操作时间上并不会有太大的差别

写在结尾

我是一名车载集成测试开发工程师,希望能和志同道合的朋友一起相互学习进步

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值