最近使用python开发web程序,一直使用的是fastcgi模式.然后每个进程中启动多个线程来进行请求处理.这里有一个问题就是需要保证每个请求响应时间都要特别短,不然只要多请求几次慢的就会让服务器拒绝服务,因为没有线程能够响应请求了.平时我们的服务上线都会进行性能测试的,所以正常情况没有太大问题.但是不可能所有场景都测试到.一旦出现就会让用户等好久没有响应.部分不可用导致全部不可用.后来转换到了coroutine,python 下的greenlet.所以对它的实现机制做了一个简单的了解.
每个greenlet都只是heap中的一个python object(PyGreenlet).所以对于一个进程你创建百万甚至千万个greenlet都没有问题.
typedef struct _greenlet {
PyObject_HEAD
char* stack_start;
char* stack_stop;
char* stack_copy;
intptr_t stack_saved;
struct _greenlet* stack_prev;
struct _greenlet* parent;
PyObject* run_info;
struct _frame* top_frame;
int recursion_depth;
PyObject* weakreflist;
PyObject* exc_type;
PyObject* exc_value;
PyObject* exc_traceback;
PyObject* dict;
} PyGreenlet;
每一个greenlet其实就是一个函数,以及保存这个函数执行时的上下文.对于函数来说上下文也就是其stack..同一个进程的所有的greenlets共用一个共同的操作系统分配的用户栈.所以同一时刻只能有栈数据不冲突的greenlet使用这个全局的栈.greenlet是通过stack_stop,stack_start来保存其stack的栈底和栈顶的,如果出现将要执行的greenlet的stack_stop和目前栈中的greenlet重叠的情况,就要把这些重叠的greenlet的栈中数据临时保存到heap中.保存的位置通过stack_copy和stack_saved来记录,以便恢复的时候从heap中拷贝回栈中stack_stop和stack_start的位置.不然就会出现其栈数据会被破坏的情况.所以应用程序创建的这些greenlet就是通过不断的拷贝数据到heap中或者从heap中拷贝到栈中来实现并发的.对于io型的应用程序使用coroutine真的非常舒服.
下面是greenlet的一个简单的栈空间模型(from greenlet.c)
A PyGreenlet is a range of C stack addresses that must be
saved and restored in such a way that the full range of the
stack contains valid data when we switch to it.
Stack layout for a greenlet:
| ^^^ |
| older data |
| |
stack_stop . |_______________|
. | |
. | greenlet data |
. | in stack |
. * |_______________| . . _____________ stack_copy + stack_saved
. | | | |
. | data | |greenlet data|
. | unrelated | | saved |
. | to | | in heap |
stack_start . | this | . . |_____________| stack_copy
| greenlet |
| |
| newer data |
| vvv |
下面是一段简单的greenlet代码.
from greenlet import greenlet
def test1():
print 12
gr2.switch()
print 34
def test2():
print 56
gr1.switch()
print 78
gr1 = greenlet(test1)
gr2 = greenlet(test2)
gr1.switch()
分享到:
相关推荐
同时,greenlet与Python的其他并发模型,如threading模块和asyncio库,也有不同的适用场景,开发者需要根据项目需求选择合适的并发机制。 总结来说,greenlet是一个用于Python的轻量级协程库,它通过greenlet对象...
Greenlet是Python中的一个库,它提供了一种轻量级的线程实现。与标准的线程相比,Greenlet之间的切换成本更低,因为它们不涉及操作系统级别的上下文切换。Greenlet的执行是完全由用户空间的代码控制的,这意味着它们...
在Python中,标准的线程库(threading模块)使用操作系统级别的线程,每个线程都有自己的调用堆栈和系统资源,而greenlet则是用户空间的实现,它们共享相同的调用堆栈和全局解释器锁(GIL)。GIL是Python解释器为了...
Python是一种广泛使用的高级编程语言,而并发编程是实现高效率、高性能程序的关键技术之一。尽管Python以其简洁的语法和强大的标准库而闻名,但它确实存在全局解释器锁(GIL),这限制了多线程程序利用多核处理器...
Erlang是一种用于构建高可用性、容错性和并发系统的编程语言,而gevent是Python中的一个库,它提供了基于协程的并发模型,通过greenlet(轻量级线程)实现非阻塞I/O,从而提高了Python在处理大量并发连接时的效率。...
总的来说,Python中的携程和`greenlet`为开发者提供了轻量级的并发机制,适用于处理高并发的I/O密集型任务。但在CPU密集型计算或需要充分利用多核资源的情况下,可能需要考虑使用线程或多进程。
Python的`dis`模块允许开发者查看和分析字节码,而一些库,如`jump`或`greenlet`,则提供了在运行时修改字节码的能力,从而实现类似goto的功能。这种方法通常用于创建复杂的循环结构或者在程序执行中改变流程,但应...
《Python中的Gevent:协程实现与应用》 在Python编程中,Gevent是一个高效的并发库,它基于Greenlet,并且提供了对协程的支持。本文将深入探讨Gevent的安装、工作原理以及如何在实际项目中应用协程。 1. **Gevent...
总的来说,gevent为Python开发者提供了一种轻量级的并发解决方案,通过greenlet和事件驱动模型,实现了高效的IO并发。它简化了异步编程的难度,让开发者能够更专注于业务逻辑,而不是并发控制。在处理网络I/O密集型...
另外,Gevent是一个基于greenlet的异步I/O库,通过协同多路复用(cooperative multitasking)实现高并发,同样支持端口复用。 在实际应用中,端口复用广泛应用于服务器程序,如HTTP服务器、FTP服务器等。Python的...
### Python几种并发实现方案的性能比较 #### 一、引言 Python作为一种广泛使用的高级编程语言,因其简洁优雅的语法和强大的库支持而备受青睐。然而,在涉及高性能计算和高并发场景的应用中,Python的标准解释器...
本文将深入探讨Python协程的定义、与线程的区别、可能遇到的问题、优势以及如何通过`yield`和`greenlet`实现简单的协程案例。 首先,协程(Coroutine)是一种可暂停和恢复的函数,它自身保存了执行状态,允许在执行...
`gevent`是一个基于greenlet的小型库,用于创建并发程序,它可以高效地管理线程,避免了线程之间的上下文切换开销。 脚本的运行流程大致如下: 1. 首先,我们需要导入必要的库,包括`grequests`、`pandas`(用于...
这些库极大地扩展了Python的功能,使得开发者可以高效地实现各种复杂任务,无论是数据处理、网络编程、科学计算还是图形用户界面设计。在本文中,我们将深入探讨Python第三方库的重要性和常用库的分类,以及如何有效...
Gevent是一个基于cooperative multitasking(协作式多任务)的Python库,它通过greenlet(轻量级线程)实现并发。与传统的多线程或多进程模型相比,gevent通过使用事件驱动和非阻塞I/O来提高性能。在MrQueue中,...
总结,基于Python的JD抢购、秒杀软件利用了Python丰富的库和强大的功能,实现了从数据抓取、解析、登录、请求到并发执行的一系列自动化操作,以提升抢购效率。开发者在实际应用中还需要关注平台规则,避免违反反爬...
在Python的世界里,有许多优秀的库为开发者提供了强大的工具,其中,`gevent`就是一款高效、并发的网络编程库,它基于greenlet实现了协程模型,极大地提升了Python应用程序的执行效率。本文将深入探讨`gevent`库,...
此外,第三方库如`gevent`和`eventlet`也提供了基于协程的并发解决方案,它们通过greenlet实现了轻量级线程,可以实现高效的并发执行。 书中可能还会涉及以下主题: - **死锁(Deadlock)**:并发编程中常见的问题...
- `gevent`: 基于greenlet实现的高级库,支持异步IO。 #### 十、课程知识点回顾 - **TCP/IP协议介绍** - **IP地址分类** - **端口、端口号** - **Socket** - **UDP通信** - **TCP通信** - **并发服务器** - **...
4. **gevent**: gevent是一个基于Greenlet的库,Greenlet类似于轻量级线程,它通过协同调度实现并发。gevent通过 monkey-patching 技术,可以无缝地将同步代码转化为异步代码,使得开发者可以使用同步风格编写异步...