当前位置: 首页 > 科技观察

要用Python实现异步编程,只需要这几步就足够了

时间:2023-03-21 12:08:48 科技观察

来源:unsplash异步编程是并行编程的一种方式。单个工作单元独立于主应用程序线程运行,并通知调用线程其完成、失败或进度。下图会更直观的理解:synchronousvsasynchronous同步编程很常见。如图,request1发出,等待response1;收到响应1后,发出请求2,然后等待其响应。上面代码中,将参数“a”传递给函数后,等待函数返回改变后的值,然后再次调用改变数字,最后再次得到响应,这就是同步编程。对于异步编程来说,request1发出后,request2可以直接发出,不需要等待response1。我是两个request完成后得到两个response。简单的说,请求1和请求2是并行处理的,不等待上一个请求的响应就发起一个新的请求。简而言之,只需打开任务管理器(macOS中的活动监视器)即可看到同时运行的多个应用程序;或者在两个不同的终端窗口中运行的PythonShell。技术术语叫做多处理(MultiProcessing),顾名思义,就是有多个进程在运行。如何在Python中进行异步编程?同步编程的示例代码如下:deffun(length,a):b=aforiinrange(length):a+=1print("valueofabefore:"+str(b)+"nowit's"+str(a))returndefmain():r1=fun(50000000,0)r2=fun(100,12)r3=fun(100,41)if__name__=="__main__":上述代码从main()的输出:这段代码传递了for的范围环形。执行代码最多耗时13.843秒,因为r1的取值范围是5000,所以耗时较长。现在的问题是必须先完成r1的任务,否则无法获得r2和r3。是否有可能在获得r1之前获得r2和r3?答案是肯定的,这就是异步编程的用武之地。首先用pip命令安装async包。pipinstallasyncio安装完成后,看看新的代码。使用异步包:importasyncioasyncdeffun(length,a):b=aforiinrange(length):a+=1ifi%10000==0:awaitasyncio.sleep(0.0001)print("valueofabefore:"+str(b)+"nowit's"+str(a))returnasyncdefmain():#creatingsubroutines.t1=loop.create_task(fun(50000000,0))t2=loop.create_task(fun(100,12))t3=loop.create_task(fun(100,41))awaitasyncio.wait([t1,t2,t3])if__name__=="__main__":loop=asyncio.get_event_loop()loop.run_until_complete(main())loop.close()先观察这段代码的输出,再讨论代码:Output-1Output-2在output-1中可以先得到t2和t3过程的结果,然后在output-2的截图中可以得到t1过程的结果,这是异步的功劳编程。t1进程耗时最长,所以它的结果最后产生,t1、t2、t3进程都是并行运行的。异步编程的好处是不需要等待任何一个过程的结果就可以得到下一个过程的结果。让我们讨论这段代码。首先在if__name__=="__main__"中定义了asyncio.get_event_loop(),这个loop作为处理循环事件的异步对象。然后创建一个主例程并设置条件:如果主程序没有完成,则继续循环。每次都是异步的,必须编程loop.close(),否则结果会出错或者异常。然后将函数定义为asyncdeffunc_name,这样解释器就知道该函数使用了异步方法。main()中定义了三个任务(也可以叫子程序),使用await函数等待三个进程结束(虽然意义不大,但不得不用)。最后,使用fun()函数。i%10000的if条件让范围最大的进程慢跑,终于得到答案。如果仔细研究fun()函数并亲自尝试一下,就会发现其中的逻辑非常合理和直白。Python中的异步编程,你学会了吗?