greenlet 模块源码
来源:互联网 发布:华为公司社会关系网络 编辑:程序博客网 时间:2024/05/21 17:07
模块初始化
greenlet是用C编写的一个扩展模块,即用Python去调用C程序。像下面这段代码,内部都是怎样的一个过程呢?
from greenlet import greenletdef test1(): print 12 gr2.switch() print 34def test2(): print 56 gr1.switch() print 78gr1 = greenlet(test1)gr2 = greenlet(test2)gr1.switch()
这段代码中,我们看到from greenlet import greenlet
这句,相信都能明白是导入了一个模块。为什么要导入这个模块呢?这个问题有点瞧不起大家了,因为我们可能需要使用这个模块的某个功能。那在导入这个模块的时候,Python解释器需要做哪些工作呢?在使用一个类的时候,我们肯定是需要调用构造函数来初始化的,导入模块就类似于这样的一个初始化过程。所以肯定会有一个初始化函数,它长啥样?
在文档中有这样一句:The initialization function must be named initname()
, where name is the name of the module, and should be the only non-static item defined in the module file.
所以对于greenlet,我们就能找到initgreenlet(void)
函数。
#define INITERROR return// 第一次导入greenlet模块时调用PyMODINIT_FUNC initgreenlet(void) { PyObject* m = NULL; char** p = NULL; PyObject *c_api_object; static void *_PyGreenlet_API[PyGreenlet_API_pointers]; GREENLET_NOINLINE_INIT(); m = Py_InitModule("greenlet", GreenMethods); if (m == NULL) { INITERROR; } ...}
首先根据模块名查找相应的初始化函数,然后Py_InitModule()
函数向Python解释器注册该模块中所有可以用到的方法。而Py_InitModule()
函数是由Python提供的C API,对于使用C API只需要包含一个头文件就可以了。
官方文档描述:All function, type and macro definitions needed to use the Python/C API are included in your code by the following line:
#include "Python.h"
方法列表
看下关键代码m = Py_InitModule("greenlet", GreenMethods)
。官方文档描述:Create a new module object based on a name and table of functions, returning the new module object.
里面提到了table of functions,在这个模块中指的就是GreenMethods
,一般称它为方法列表。该列表给出了所有可以被Python解释器使用的方法,将这些方法注册到这个模块中,这样在我们导入模块后就可以直接使用了。
当Python程序第一次导入greenlet模块的时候,调用initgreenlet()
函数。接着Py_InitModule()
会创建一个“模块对象”(它将被插入到sys.modules
字典下的“greenlet”键下),并且将方法列表(PyMethodDef结构数组)构成的内建函数对象作为它的第二个参数传到刚被创建的模块中。Py_InitModule()
返回一个指向它创建的模块对象的指针。方法列表代码:
static PyMethodDef GreenMethods[] = { {"getcurrent", (PyCFunction)mod_getcurrent, METH_NOARGS, /*XXX*/ NULL}, ...};
方法列表中的各项参数如下:
(PyCFunction)mod_getcurrent
函数如下:
static PyObject* mod_getcurrent(PyObject* self){ if (!STATE_OK) return NULL; Py_INCREF(ts_current); return (PyObject*) ts_current;}
该函数的作用就是获取当前greenlet对象,并添加引用计数。
小结
一个模块的初始化工作大致是这样的。不过针对greenlet发现了一些问题,在该模块的方法列表中看到了getcurrent
,而其他像switch
、run
等却没有看到。随后去查阅greenlet的官方文档,看到了greenlet.getcurrent()
和g.switch(*args, **kwargs)
,却被分别安排在『实例化』和『greenlets的方法和属性』两个不同的标题之下,为什么要这样区分呢?
以上部分都是一个Python C扩展模块基本的初始化工作,针对greenlet还有其他要做的。具体怎么做以及上面问题的答案就放到下一篇讲吧,因为内容比较多在这篇讲不完。
- greenlet 模块源码
- python并发编程greenlet模块学习
- python协程的实现(greenlet源码分析)
- [gevent源码分析] gevent两架马车-libev和greenlet
- gevent 学习笔记 —— greenlet源码剖析1
- [gevent源码分析] gevent两架马车-libev和greenlet
- python协程的实现(greenlet源码分析)
- greenlet implemenation
- python greenlet
- Python greenlet
- greenlet 详解
- greenlet 详解
- greenlet 详解
- greenlet 详解
- python greenlet 实现机制
- greenlet switch原理猜测
- greenlet: Lightweight concurrent programming
- Python 之 greenlet
- 每个架构师都应该研究下康威定律
- resin 安装配置
- Oracle OAF 问题集锦 - 迁移oaf后有些site层不能编辑
- bookshelf.js笔记
- php初步入门(四)
- greenlet 模块源码
- 10个方法让程序员更加优秀
- jQuery属性选择器
- Servlet学习二
- HZAU1098: Yifan and War3(区间dp)
- 开通
- android中xmlns:tools属性详解
- Oracle中start with…connect by prior子句用法
- fonts/fontawesome-webfont.woff2 404