当前位置:首页 > 数码 > 深入探讨现代并发开发-Python协程与异步编程 (深入探讨一下)

深入探讨现代并发开发-Python协程与异步编程 (深入探讨一下)

admin7个月前 (04-18)数码31

引言

在现代计算中,处理并发和异步任务至关重要。Python 为这些场景提供了两种强大的机制: 协程和异步编程。

深入探讨现代并发开发

协程

协程是一种轻量级的并发编程方式。它允许程序在执行过程中暂停和恢复,以便处理其他任务。与线程不同,协程在单个 CPU 上运行,这使得它们比线程更轻量级,开销也更低。

协程的优点

  • 更轻量级和更低的开销
  • 更容易编写和管理
  • 避免了线程同步问题

异步编程

异步编程模型是一种基于协程的编程风格。它使用非阻塞的异步 IO 操作来提高程序的并发性能。异步 IO 在后台进行,而程序可以继续执行其他任务,从而避免了阻塞。

异步编程的优点

  • 更高的并发性
  • 更低的延迟
  • 更有效的资源利用

协程和异步编程在 Python 中的使用

Python 提供了几个内置的库和框架来支持协程和异步编程:

  • asyncio: Python 3.4 中引入的标准库,它提供了异步编程的框架和工具。
  • gevent: 一个第三方库,它为协程和异步编程提供了更高级别的抽象。
  • Twisted: 另一个第三方库,它提供了用于网络编程和事件驱动的异步编程的框架。

示例: 使用 asyncio 实现异步 HTTP 服务器

下面的代码示例展示了如何使用 asyncio 在 Python 中实现一个简单的异步 HTTP 服务器:


import asyncio

async def handle_request(reader, writer):
    data = await reader.read(1024)
    message = 'Hello World!'
    writer.write(message.encode())

async def main():
    server = await asyncio.start_server(handle_request, '127.0.0.1', 8888)
    await server.serve_forever()

if __name__ == '__main__':
    asyncio.run(main())

结论

协程和异步编程是处理并发和异步任务的强大工具。它们可以显着提高 Python 程序的并发性和性能。通过理解和利用这些概念,开发人员可以创建健壮且高效的应用程序,以满足现代计算的需求。


如何用Python一门语言通吃高性能并发,GPU计算和深度学习

第一个就是并发本身所带来的开销即新开处理线程、关闭处理线程、多个处理线程时间片轮转所带来的开销。 实际上对于一些逻辑不那么复杂的场景来说这些开销甚至比真正的处理逻辑部分代码的开销更大。 所以我们决定采用基于协程的并发方式,即服务进程只有一个(单cpu)所有的请求数据都由这个服务进程内部来维护,同时服务进程自行调度不同请求的处理顺序,这样避免了传统多线程并发方式新建、销毁以及系统调度处理线程的开销。 基于这样的考虑我们选择了基于Tornado框架实现api服务的开发。 Tornado的实现非常简洁明了,使用python的生成器作为协程,利用IOLoop实现了调度队列。 第二个问题是数据库的性能,这里说的数据库包括MongoDB和Redis,我这里分开讲。 先讲MongoDB的问题,MongoDB主要存储不同的用户对于验证的不同设置,比如该显示什么样的图片。 一开始每次验证请求都会查询MongoDB,当时我们的MongoDB是纯内存的,同时三台机器组成一个复制集,这样的组合大概能稳定承载八九千的qps,后来随着我们验证量越来越大,这个承载能力逐渐就成为了我们的瓶颈。 为了彻底搞定这个问题,我们提出了最极端的解决方案,干脆直接把数据库中的数据完全缓存到服务进程里定期批量更新,这样查询的开销将大大降低。 但是因为我们用的是Python,由于GIL的存在,在8核服务器上会fork出来8个服务进程,进程之间不像线程那么方便,所以我们基于mmap自己写了一套伙伴算法构建了一个跨进程共享缓存。 自从这套缓存上线之后,Mongodb的负载几乎变成了零。 说完了MongoDB再说Redis的问题,Redis代码简洁、数据结构丰富、性能强大,唯一的问题是作为一个单进程程序,终究性能是有上限的。 虽然今年Redis发布了官方的集群版本,但是经过我们的测试,认为这套分布式方案的故障恢复时间不够优秀并且运维成本较高。 在Redis官方集群方案面世之前,开源世界有不少proxy方案,比如Twtter的TwemProxy和豌豆荚的Codis。 这两种方案测试完之后给我们的感觉TwemProxy运维还是比较麻烦,Codis使用起来让人非常心旷神怡,无论是修改配置还是扩容都可以在配置页面上完成,并且性能也还算不错,但无奈当时Codis还有比较严重的BUG只能放弃之。 几乎尝试过各种方案之后,我们还是下决心自己实现一套分布式方案,目的是高度贴合我们的需求并且运维成本要低、扩容要方便、故障切换要快最重要的是数据冗余一定要做好。 基于上面的考虑,我们确定基于客户端的分布式方案,通过zookeeper来同步状态保证高可用。 具体来说,我们修改Redis源码,使其向zookeeper注册,客户端由zookeeper上获取Redis服务器集群信息并根据统一的一致性哈希算法来计算数据应该存储在哪台Redis上,并在哈希环的下一台Redis上写入一份冗余数据,当读取原始数据失败时可以立即尝试读取冗余数据而不会造成服务中断。

如何实现并发执行100个耗时的请求?

对于并发处理100个耗时请求,可以使用FastAPI框架的异步特性来实现。 FastAPI支持使用Python的异步特性,如async/await和asyncio模块,来处理并发请求。 它可以利用Python的协程和事件循环机制,实现高效的并发处理。 具体实现方法如下:1. 使用async/await关键字定义异步函数,用于处理耗时的请求。 在这些函数内部,可以使用await关键字来暂停当前的异步函数,等待其他耗时操作完成。 2. 使用asyncio模块创建一个事件循环,用于管理并发的异步任务。 事件循环可以通过调用异步函数来执行并发请求的处理。 3. 在FastAPI的路由函数中,使用async/await关键字调用异步函数,并将其包装在一个协程中。 这样,当路由函数被调用时,它会立即返回一个协程对象,而不会阻塞其他请求的处理。 4. 使用()函数来同时运行多个协程对象,实现并发处理。 这个函数可以接收一个协程对象的列表作为参数,并返回一个包含所有协程结果的列表。 使用上述方法,FastAPI可以有效地处理并发的耗时请求。 通过利用Python的异步特性,它可以在一个事件循环中同时处理多个请求,而不会阻塞其他请求的处理。 这样可以大大提高系统的并发能力和性能。 除了使用异步特性处理并发请求外,还可以通过一些优化措施进一步提升性能,如合理使用连接池、使用缓存技术、使用异步数据库驱动等。 这些方法可以减少不必要的网络延迟和数据库访问时间,提高系统的并发处理能力。 总之,使用FastAPI框架的异步特性,结合合适的优化措施,可以实现高效的并发处理,同时处理多个耗时请求。 这对于构建高性能的Web应用程序非常有益。

免责声明:本文转载或采集自网络,版权归原作者所有。本网站刊发此文旨在传递更多信息,并不代表本网赞同其观点和对其真实性负责。如涉及版权、内容等问题,请联系本网,我们将在第一时间删除。同时,本网站不对所刊发内容的准确性、真实性、完整性、及时性、原创性等进行保证,请读者仅作参考,并请自行核实相关内容。对于因使用或依赖本文内容所产生的任何直接或间接损失,本网站不承担任何责任。

标签: Python

“深入探讨现代并发开发-Python协程与异步编程 (深入探讨一下)” 的相关文章

b-b-个入门建议!-Python-技术书籍推荐-附赠-11 (b+b+b等于什么)

b-b-个入门建议!-Python-技术书籍推荐-附赠-11 (b+b+b等于什么)

近年来,Python 持续火爆,越来越多的人开始入门学习 Python。RealPython 作为最受好评的 Python 学习网站,拥有超百万的浏览量,以下是 RealPython 的开发者给...

Python中的Random模块-摸索随机性的神奇环球 (python编程)

Python中的Random模块-摸索随机性的神奇环球 (python编程)

随机性在计算机编程和数据迷信中表演着至关关键的角色。/target=_blankclass=infotextkey>Python中的random模块提供了丰盛的工具和函数,协助咱们生成随机数...

惰性求值和lambda表达式的强大组合-Python高级技巧 (惰性求值和逻辑短路)

惰性求值和lambda表达式的强大组合-Python高级技巧 (惰性求值和逻辑短路)

Lambda 表达式 在 Python 中,Lambda 表达式是一个匿名函数,它可以在需要函数对象的地方使用。Lambda 表达式的语法如下: lambda arguments: exp...

掌握网络世界的无限可能-Python分布式爬虫助力搜索引擎打造 (掌握网络世界的好处)

掌握网络世界的无限可能-Python分布式爬虫助力搜索引擎打造 (掌握网络世界的好处)

主从模式 主从模式是一种简单的分布式爬虫架构,其中一台主机作为控制节点,负责管理所有运行爬虫的从机。 主节点负责向从机分配任务,并接收新生成的任务。从机只需要从主节点接收任务,并把新生...

生成-UUID-操作-Python-齐全指南-格局和经常出现疑问 (生成uuid java)

生成-UUID-操作-Python-齐全指南-格局和经常出现疑问 (生成uuid java)

UUID(UniversallyUniqueIdentifier,通用惟一标识符)是一种全局惟一标识符生成形式,用于创立举世无双的标识符。/target=_blankclass=infotextk...

使用Python进行数据分析的步骤 (使用pycharm)

使用Python进行数据分析的步骤 (使用pycharm)

简介 Python 是一种动态的、面向对象的脚本语言,以其简单性和易读性而闻名。它广泛用于数据分析,因为它具有强大的库,兼容开源大数据平台 Hadoop,并且拥有众多优势,使其成为流行的编...

网络-摸索Python中的必备模块-解锁数据处置-迷信计算等畛域的弱小工具-自动化 (网络mod)

网络-摸索Python中的必备模块-解锁数据处置-迷信计算等畛域的弱小工具-自动化 (网络mod)

/target=_blankclass=infotextkey>Python罕用的模块十分多,关键分为内置模块和第三方模块两大类,且不同模块运行场景不同又可以分为文本类、数据结构类、数学运算...

内置数据库-的长处和运行-SQLite-轻量级-Python (内置数据库)

内置数据库-的长处和运行-SQLite-轻量级-Python (内置数据库)

/target=_blankclass=infotextkey>Python是一种盛行的编程言语,可以用于开发各种运行程序,从图形用户界面到网站和游戏。Python的一个特点是,它内置了一个...