`
kmoving
  • 浏览: 12108 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
最近访客 更多访客>>
文章分类
社区版块
存档分类
最新评论

python greenlet 实现机制

阅读更多
最近使用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()
0
0
分享到:
评论

相关推荐

    PyPI 官网下载 | greenlet-0.4.3.win-amd64-py2.7.exe

    同时,greenlet与Python的其他并发模型,如threading模块和asyncio库,也有不同的适用场景,开发者需要根据项目需求选择合适的并发机制。 总结来说,greenlet是一个用于Python的轻量级协程库,它通过greenlet对象...

    Python-diesel基于Greenlet的事件IOPython框架

    Greenlet是Python中的一个库,它提供了一种轻量级的线程实现。与标准的线程相比,Greenlet之间的切换成本更低,因为它们不涉及操作系统级别的上下文切换。Greenlet的执行是完全由用户空间的代码控制的,这意味着它们...

    Python库 | greenlet-0.4.0-py2.7-win-amd64.egg

    在Python中,标准的线程库(threading模块)使用操作系统级别的线程,每个线程都有自己的调用堆栈和系统资源,而greenlet则是用户空间的实现,它们共享相同的调用堆栈和全局解释器锁(GIL)。GIL是Python解释器为了...

    使用Python中的greenlet包实现并发编程的入门教程

    Python是一种广泛使用的高级编程语言,而并发编程是实现高效率、高性能程序的关键技术之一。尽管Python以其简洁的语法和强大的标准库而闻名,但它确实存在全局解释器锁(GIL),这限制了多线程程序利用多核处理器...

    Python-一个用Python实现的Erlang结点使用gevent库

    Erlang是一种用于构建高可用性、容错性和并发系统的编程语言,而gevent是Python中的一个库,它提供了基于协程的并发模型,通过greenlet(轻量级线程)实现非阻塞I/O,从而提高了Python在处理大量并发连接时的效率。...

    python3之携程yield及greenlet

    总的来说,Python中的携程和`greenlet`为开发者提供了轻量级的并发机制,适用于处理高并发的I/O密集型任务。但在CPU密集型计算或需要充分利用多核资源的情况下,可能需要考虑使用线程或多进程。

    Python-pythongoto函式修饰符对bytecode进行重定向Python中的goto

    Python的`dis`模块允许开发者查看和分析字节码,而一些库,如`jump`或`greenlet`,则提供了在运行时修改字节码的能力,从而实现类似goto的功能。这种方法通常用于创建复杂的循环结构或者在程序执行中改变流程,但应...

    python-gevent-20.9.0.tar.gz

    《Python中的Gevent:协程实现与应用》 在Python编程中,Gevent是一个高效的并发库,它基于Greenlet,并且提供了对协程的支持。本文将深入探讨Gevent的安装、工作原理以及如何在实际项目中应用协程。 1. **Gevent...

    Python-gevent轻量级进程内的并发编程

    总的来说,gevent为Python开发者提供了一种轻量级的并发解决方案,通过greenlet和事件驱动模型,实现了高效的IO并发。它简化了异步编程的难度,让开发者能够更专注于业务逻辑,而不是并发控制。在处理网络I/O密集型...

    Python-端口复用相关思路和工具

    另外,Gevent是一个基于greenlet的异步I/O库,通过协同多路复用(cooperative multitasking)实现高并发,同样支持端口复用。 在实际应用中,端口复用广泛应用于服务器程序,如HTTP服务器、FTP服务器等。Python的...

    python几种并发实现方案的性能比较.docx

    ### Python几种并发实现方案的性能比较 #### 一、引言 Python作为一种广泛使用的高级编程语言,因其简洁优雅的语法和强大的库支持而备受青睐。然而,在涉及高性能计算和高并发场景的应用中,Python的标准解释器...

    Python中协程用法代码详解

    本文将深入探讨Python协程的定义、与线程的区别、可能遇到的问题、优势以及如何通过`yield`和`greenlet`实现简单的协程案例。 首先,协程(Coroutine)是一种可暂停和恢复的函数,它自身保存了执行状态,允许在执行...

    python多线程批量访问url脚本

    `gevent`是一个基于greenlet的小型库,用于创建并发程序,它可以高效地管理线程,避免了线程之间的上下文切换开销。 脚本的运行流程大致如下: 1. 首先,我们需要导入必要的库,包括`grequests`、`pandas`(用于...

    python第三方库

    这些库极大地扩展了Python的功能,使得开发者可以高效地实现各种复杂任务,无论是数据处理、网络编程、科学计算还是图形用户界面设计。在本文中,我们将深入探讨Python第三方库的重要性和常用库的分类,以及如何有效...

    Python-MrQueue一个Python的分布式worker任务队列使用Redis和gevent

    Gevent是一个基于cooperative multitasking(协作式多任务)的Python库,它通过greenlet(轻量级线程)实现并发。与传统的多线程或多进程模型相比,gevent通过使用事件驱动和非阻塞I/O来提高性能。在MrQueue中,...

    基于python的JD抢购,秒杀软件.zip

    总结,基于Python的JD抢购、秒杀软件利用了Python丰富的库和强大的功能,实现了从数据抓取、解析、登录、请求到并发执行的一系列自动化操作,以提升抢购效率。开发者在实际应用中还需要关注平台规则,避免违反反爬...

    Python库 | gevent-1.5a4-cp35-cp35m-manylinux2010_x86_64.whl

    在Python的世界里,有许多优秀的库为开发者提供了强大的工具,其中,`gevent`就是一款高效、并发的网络编程库,它基于greenlet实现了协程模型,极大地提升了Python应用程序的执行效率。本文将深入探讨`gevent`库,...

    Learning Concurrency in Python(pdf+epub+mobi+code_files).zip

    此外,第三方库如`gevent`和`eventlet`也提供了基于协程的并发解决方案,它们通过greenlet实现了轻量级线程,可以实现高效的并发执行。 书中可能还会涉及以下主题: - **死锁(Deadlock)**:并发编程中常见的问题...

    python网络编程

    - `gevent`: 基于greenlet实现的高级库,支持异步IO。 #### 十、课程知识点回顾 - **TCP/IP协议介绍** - **IP地址分类** - **端口、端口号** - **Socket** - **UDP通信** - **TCP通信** - **并发服务器** - **...

    Python高性能网络编程并发框架研究.zip

    4. **gevent**: gevent是一个基于Greenlet的库,Greenlet类似于轻量级线程,它通过协同调度实现并发。gevent通过 monkey-patching 技术,可以无缝地将同步代码转化为异步代码,使得开发者可以使用同步风格编写异步...

Global site tag (gtag.js) - Google Analytics