python async异步编程

demo_udp_server.py

import time
import socket
import threading


def func(s, data, addr):
    i = int(data.decode("utf-8"))
    start_time = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
    time.sleep(i)
    end_time = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
    s.sendto("序号:{},地址:{},开始时间:{},结束时间:{}".format(i, addr, start_time, end_time).encode("utf-8"), addr)


if __name__ == '__main__':
    s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    s.bind(("0.0.0.0", 3399))
    while True:
        data, addr = s.recvfrom(1024 * 1024)
        threading.Thread(target=func, args=(s, data, addr)).start()
    s.close()

demo_udp_client.py

import asyncio
import time
import socket


class Client:
    def __init__(self):
        self.__send_number = 0
        self.__recv_number = 0

    async def send(self, data):
        c = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        c.sendto(str(data).encode("utf-8"), ("127.0.0.1", 3399))
        self.__send_number += 1
        data, addr = await asyncio.get_event_loop().run_in_executor(None, c.recvfrom, 1024 * 1024)
        self.__recv_number += 1
        c.close()
        return data.decode("utf-8")

    async def main(self):
        tasks = [asyncio.ensure_future(self.send(i)) for i in range(5)]
        for task in asyncio.as_completed(tasks):
            print(f"当前已发送数:{self.__send_number},当前已返回数:{self.__recv_number},本次返回数据:{await task}")

    def run(self):
        s = time.time()
        asyncio.run(self.main())
        e = time.time()
        print("执行结束,耗时:", e - s)


if __name__ == '__main__':
    Client().run()

运行结果:

当前已发送数:0,当前已返回数:0,本次返回数据:序号:0,地址:('127.0.0.1', 51743),开始时间:2020-07-29 16:33:43,结束时间:2020-07-29 16:33:43
当前已发送数:5,当前已返回数:1,本次返回数据:序号:1,地址:('127.0.0.1', 51744),开始时间:2020-07-29 16:33:43,结束时间:2020-07-29 16:33:44
当前已发送数:5,当前已返回数:2,本次返回数据:序号:2,地址:('127.0.0.1', 51745),开始时间:2020-07-29 16:33:43,结束时间:2020-07-29 16:33:45
当前已发送数:5,当前已返回数:3,本次返回数据:序号:3,地址:('127.0.0.1', 51746),开始时间:2020-07-29 16:33:43,结束时间:2020-07-29 16:33:46
当前已发送数:5,当前已返回数:4,本次返回数据:序号:4,地址:('127.0.0.1', 51747),开始时间:2020-07-29 16:33:43,结束时间:2020-07-29 16:33:47
执行结束,耗时: 4.016651630401611

 

demo_socket.py

import socket
import time
import asyncio


rsp_hearder = """
HTTP/1.1 200 OK
content-type: text/html; charset=UTF-8

"""


async def rsp_func(data):
    # 输入开始时间
    rsp_data = "<div style='color: red;'><b>开始时间,{}</b></div>".format(time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()))
    # 挂起5秒
    await asyncio.sleep(5)
    # 输入结束时间
    rsp_data += "<div style='color: red;'><b>结束时间,{}</b></div>".format(time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()))
    rsp_data += "<div><p>{}</p></div>".format("</p><p>".join(data.decode("utf-8").split("\r\n")))
    return rsp_data


async def con_func(s):
    con, addr = s.accept()
    data = con.recv(1024)
    rsp_data = await rsp_func(data)
    con.send((rsp_hearder + rsp_data).encode("utf-8"))
    con.close()
    return True


async def main_func(s):
    aaa = asyncio.create_task(con_func(s))
    bbb = asyncio.create_task(con_func(s))
    ccc = asyncio.create_task(con_func(s))
    await aaa
    await bbb
    await ccc


if __name__ == '__main__':
    s = socket.socket()
    s.bind(("0.0.0.0", 3399))
    s.listen(5)
    asyncio.run(main_func(s))

运行结果(注意看开始时间和结束时间):

 

 

 

 

 

demo_egg.py

import time
import random
import asyncio


class Egg:
    def __repr__(self):
        return f"{id(self)}"


class Factory:
    eggs = list()

    async def make(self):
        make_time = random.random() * 10
        make_number = random.randint(1, 10)
        await asyncio.sleep(make_time)
        for i in range(make_number):
            self.eggs.append(Egg())
        return make_time, make_number


class Producer:
    def __init__(self):
        self.__factory = Factory()

    async def make(self, consumer_name):
        make_time, make_number = await self.__factory.make()
        print(f"应消费者 {consumer_name} 的要求,本次生产鸡蛋 {make_number} 个,生产耗时 {make_time}。")


class Consumer:
    def __init__(self, name):
        self.__name = name
        self.__factory = Factory()
        self.__producer = Producer()

    async def take(self, number):
        take_number = 0
        bucket = list()
        start = time.time()
        while take_number < number:
            if not self.__factory.eggs:
                await self.__producer.make(self.__name)
            bucket.append(self.__factory.eggs.pop())
            take_number += 1
        end = time.time()
        print(f"消费者 {self.__name} 完成消费,共耗时 {end - start},所消费鸡蛋编号:{bucket}")
        return bucket


if __name__ == '__main__':
    consumers_info = dict(A=13, B=26, C=18, D=24)       # 消费者信息,key为消费者代号,value为消费者需要消费的个数
    consumers_task = [Consumer(key).take(value) for key, value in consumers_info.items()]       # 创建消费者任务
    loop = asyncio.get_event_loop()
    start = time.time()
    loop.run_until_complete(asyncio.wait(consumers_task))       # 开始消费
    end = time.time()
    print(f"所有消费者完成消费,耗时:{end - start}")
    loop.close()

运行结果一:

应消费者 D 的要求,本次生产鸡蛋 6 个,生产耗时 2.055247798050898。
应消费者 D 的要求,本次生产鸡蛋 5 个,生产耗时 0.6757228878993815。
应消费者 B 的要求,本次生产鸡蛋 5 个,生产耗时 3.944825748266293。
应消费者 A 的要求,本次生产鸡蛋 8 个,生产耗时 6.508075667028388。
应消费者 B 的要求,本次生产鸡蛋 4 个,生产耗时 3.830290023652332。
应消费者 B 的要求,本次生产鸡蛋 9 个,生产耗时 0.1633607042539953。
应消费者 C 的要求,本次生产鸡蛋 9 个,生产耗时 8.275439346199498。
应消费者 A 的要求,本次生产鸡蛋 3 个,生产耗时 1.985968761240161。
应消费者 A 的要求,本次生产鸡蛋 5 个,生产耗时 0.1851587562492818。
消费者 A 完成消费,共耗时 8.695606231689453,所消费鸡蛋编号:[1463880960560, 1463880960512, 1463880960464, 1463880960416, 1463880960368, 1463880960320, 1463880960272, 1463880959456, 1463880961760, 1463880961712, 1463880959312, 1463880962000, 1463880961952]
应消费者 D 的要求,本次生产鸡蛋 2 个,生产耗时 7.9511431033838225。
应消费者 C 的要求,本次生产鸡蛋 7 个,生产耗时 2.515700996900337。
应消费者 B 的要求,本次生产鸡蛋 3 个,生产耗时 4.766686328544342。
应消费者 D 的要求,本次生产鸡蛋 8 个,生产耗时 5.551008152337591。
消费者 D 完成消费,共耗时 16.25092101097107,所消费鸡蛋编号:[1463880959696, 1463880959648, 1463880959600, 1463880959552, 1463880959504, 1463880958928, 1463880959936, 1463880959888, 1463880959840, 1463880959792, 1463880959360, 1463873062416, 1463880961808, 1463880961904, 1463880961856, 1463880960608, 1463880995456, 1463880995408, 1463880995360, 1463880995312, 1463880995264, 1463880995216, 1463880995168, 1463880961232]
应消费者 B 的要求,本次生产鸡蛋 10 个,生产耗时 3.8596989808175297。
消费者 B 完成消费,共耗时 16.54865550994873,所消费鸡蛋编号:[1463880960176, 1463880960128, 1463880960080, 1463880960032, 1463880959744, 1463880960752, 1463880960704, 1463880960656, 1463880959408, 1463880961184, 1463880961136, 1463880961088, 1463880961040, 1463880960992, 1463880960944, 1463880960896, 1463880960848, 1463880960224, 1463880995072, 1463880995024, 1463880961664, 1463880995600, 1463880995552, 1463880995504, 1463880863696, 1463880863648]
应消费者 C 的要求,本次生产鸡蛋 6 个,生产耗时 6.74875430837098。
消费者 C 完成消费,共耗时 17.547677278518677,所消费鸡蛋编号:[1463880961616, 1463880961568, 1463880961520, 1463880961472, 1463880961424, 1463880961376, 1463880961328, 1463880961280, 1463880960800, 1463880994928, 1463880994880, 1463872886384, 1463872885136, 1463872886480, 1463873347984, 1463880959984, 1463873464544, 1463873464832]
所有消费者完成消费,耗时:17.547677278518677

运行结果二:

应消费者 D 的要求,本次生产鸡蛋 9 个,生产耗时 1.6482069373699504。
应消费者 D 的要求,本次生产鸡蛋 5 个,生产耗时 2.724804536288813。
应消费者 C 的要求,本次生产鸡蛋 3 个,生产耗时 6.5521891899452385。
应消费者 A 的要求,本次生产鸡蛋 1 个,生产耗时 7.116534454485729。
应消费者 B 的要求,本次生产鸡蛋 6 个,生产耗时 9.90740877477853。
应消费者 C 的要求,本次生产鸡蛋 9 个,生产耗时 3.450395271592861。
应消费者 D 的要求,本次生产鸡蛋 5 个,生产耗时 8.577977664255176。
应消费者 A 的要求,本次生产鸡蛋 8 个,生产耗时 6.594023851538519。
应消费者 A 的要求,本次生产鸡蛋 2 个,生产耗时 4.379926715060693。
应消费者 C 的要求,本次生产鸡蛋 9 个,生产耗时 8.111939377346335。
消费者 C 完成消费,共耗时 18.11986804008484,所消费鸡蛋编号:[3250466572512, 3250466572464, 3250466572176, 3250466573280, 3250466573232, 3250466573184, 3250466573136, 3250466573088, 3250466573040, 3250466572992, 3250466572944, 3250466571744, 3250466611360, 3250466611312, 3250466611264, 3250466574288, 3250466574240, 3250466574192]
应消费者 B 的要求,本次生产鸡蛋 3 个,生产耗时 8.312759029068811。
应消费者 D 的要求,本次生产鸡蛋 9 个,生产耗时 8.68971173941737。
消费者 D 完成消费,共耗时 21.6379234790802,所消费鸡蛋编号:[3250466572128, 3250466572080, 3250466572032, 3250466571984, 3250466571936, 3250466571888, 3250466571840, 3250466571792, 3250466571216, 3250466572368, 3250466572320, 3250466572272, 3250466572224, 3250466571648, 3250466573520, 3250466573472, 3250466573424, 3250466573376, 3250466572560, 3250466611600, 3250466611552, 3250466611504, 3250466611456, 3250466611408]
应消费者 A 的要求,本次生产鸡蛋 8 个,生产耗时 3.7250585716995674。
消费者 A 完成消费,共耗时 21.816943168640137,所消费鸡蛋编号:[3250466571600, 3250466573904, 3250466573856, 3250466573808, 3250466573760, 3250466573712, 3250466573664, 3250466573616, 3250466572416, 3250466574000, 3250466572608, 3250466611648, 3250466475984]
应消费者 B 的要求,本次生产鸡蛋 4 个,生产耗时 9.256365785455493。
消费者 B 完成消费,共耗时 27.48068332672119,所消费鸡蛋编号:[3250466572848, 3250466572800, 3250466572752, 3250466572704, 3250466572656, 3250466571696, 3250465970544, 3250465968480, 3250466573328, 3250466574144, 3250466574096, 3250466573952, 3250458960272, 3250458962768, 3250458674704, 3250466574048, 3250466475936, 3250466570352, 3250466570400, 3250466570304, 3250466573568, 3250465970592, 3250465918784, 3250465918736, 3250465918448, 3250466572896]
所有消费者完成消费,耗时:27.48068332672119

运行结果三:

应消费者 A 的要求,本次生产鸡蛋 1 个,生产耗时 2.6399731996608047。
应消费者 B 的要求,本次生产鸡蛋 9 个,生产耗时 8.098189886207706。
应消费者 C 的要求,本次生产鸡蛋 9 个,生产耗时 8.548621423119974。
应消费者 D 的要求,本次生产鸡蛋 7 个,生产耗时 8.59538106011149。
应消费者 C 的要求,本次生产鸡蛋 3 个,生产耗时 1.4300446901044483。
应消费者 A 的要求,本次生产鸡蛋 5 个,生产耗时 8.655737726596335。
应消费者 D 的要求,本次生产鸡蛋 6 个,生产耗时 4.078791401515385。
应消费者 C 的要求,本次生产鸡蛋 3 个,生产耗时 3.5374332053710313。
应消费者 B 的要求,本次生产鸡蛋 8 个,生产耗时 7.0179847215760045。
应消费者 D 的要求,本次生产鸡蛋 9 个,生产耗时 3.5529888815119826。
应消费者 D 的要求,本次生产鸡蛋 6 个,生产耗时 0.2202203380148482。
消费者 D 完成消费,共耗时 16.46090006828308,所消费鸡蛋编号:[2703832042128, 2703832042080, 2703832042032, 2703832041984, 2703832041936, 2703832041888, 2703832040784, 2703832042800, 2703832042752, 2703832042704, 2703832042656, 2703832042608, 2703832040976, 2703832076592, 2703832076544, 2703832076496, 2703832076448, 2703832076400, 2703832076352, 2703832043472, 2703832043424, 2703832041408, 2703832076880, 2703832076832]
应消费者 B 的要求,本次生产鸡蛋 5 个,生产耗时 1.7211145437731978。
消费者 B 完成消费,共耗时 16.824620962142944,所消费鸡蛋编号:[2703832041360, 2703832041312, 2703832041264, 2703832041216, 2703832041168, 2703832041120, 2703832041072, 2703832041024, 2703832040880, 2703832043328, 2703832043280, 2703832043232, 2703832043184, 2703832043136, 2703832043088, 2703832043040, 2703832042320, 2703831945120, 2703832039536, 2703832039584, 2703832039488, 2703831439776, 2703832076784, 2703832076736, 2703832076688, 2703832042848]
应消费者 C 的要求,本次生产鸡蛋 1 个,生产耗时 6.230255375873305。
应消费者 A 的要求,本次生产鸡蛋 3 个,生产耗时 9.499757970081745。
应消费者 C 的要求,本次生产鸡蛋 8 个,生产耗时 2.1394171609610533。
消费者 C 完成消费,共耗时 21.884315729141235,所消费鸡蛋编号:[2703832041792, 2703832041744, 2703832041696, 2703832041648, 2703832041600, 2703832041552, 2703832041504, 2703832041456, 2703832040928, 2703832042272, 2703832042224, 2703832040832, 2703832042944, 2703832042896, 2703832042176, 2703832043376, 2703832077024, 2703832076976]
应消费者 A 的要求,本次生产鸡蛋 4 个,生产耗时 9.331730225097903。
消费者 A 完成消费,共耗时 30.12247061729431,所消费鸡蛋编号:[2703832040400, 2703832042512, 2703832042464, 2703832042416, 2703832042368, 2703832041840, 2703831387488, 2703826269808, 2703832042992, 2703831439680, 2703831439728, 2703831437664, 2703827463952]
所有消费者完成消费,耗时:30.12247061729431

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
异步编程是一种编程模式,它允许程序在等待某些操作完成时继续执行其他任务,而不是阻塞整个程序的执行。Python中的异步编程可以使用`async`和`await`关键字来实现。 `async`关键字用于定义一个异步函数,这个函数可以使用`await`关键字来挂起自身的执行,等待其他的异步操作完成后再继续执行。 下面是一个简单的例子,展示了如何使用`async`和`await`来实现异步编程: ```python import asyncio async def async_task(): print("异步任务开始") await asyncio.sleep(1) # 模拟耗时操作 print("异步任务结束") async def main(): print("主程序开始") await asyncio.gather(async_task(), async_task()) # 并发执行两个异步任务 print("主程序结束") asyncio.run(main()) ``` 在上面的例子中,我们定义了一个异步函数`async_task()`,它会打印一些信息,然后使用`await asyncio.sleep(1)`来模拟一个耗时操作。然后我们定义了另一个异步函数`main()`,它会并发地执行两个`async_task()`函数。最后,在`asyncio.run(main())`中运行主程序。 通过运行上面的代码,你会看到输出的顺序是"主程序开始" -> "异步任务开始" -> "异步任务开始" -> "异步任务结束" -> "异步任务结束" -> "主程序结束"。可以看到,在执行异步任务时,主程序不会被阻塞,而是继续执行其他任务。 异步编程在处理I/O密集型任务时特别有用,因为它可以充分利用等待I/O操作完成的时间,同时执行其他任务,提高程序的性能和响应性。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值