摘要:不過不管怎樣,就當(dāng)多學(xué)習(xí)了一些其他知識(shí),況且分析源碼肯定少不了對(duì)這些知識(shí)的了解。官方文檔描述里面提到了,在這個(gè)模塊中指的就是,一般稱它為方法列表。返回一個(gè)指向它創(chuàng)建的模塊對(duì)象的指針。
在greenlet篇中只是簡(jiǎn)單講述了一下greenlet原理,不知道有沒有人對(duì)源碼感興趣的,不過我還是比較感興趣的。對(duì)于技術(shù)我一直都覺得『知其然,知其所以然』才是最好的,不希望自己只停留在知道用,而不知道為什么這樣用。
一篇可能介紹不完,所以可能需要分幾部分來介紹。當(dāng)我寫到這的時(shí)候突然發(fā)現(xiàn)自己是不是寫跑題了,本來是寫greenlet源碼分析的,結(jié)果變成了怎么去寫Python擴(kuò)展了。不過不管怎樣,就當(dāng)多學(xué)習(xí)了一些其他知識(shí),況且分析源碼肯定少不了對(duì)這些知識(shí)的了解。
模塊初始化greenlet是用C編寫的一個(gè)擴(kuò)展模塊,即用Python去調(diào)用C程序。像下面這段代碼,內(nèi)部都是怎樣的一個(gè)過程呢?
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()
這段代碼中,我們看到from greenlet import greenlet這句,相信都能明白是導(dǎo)入了一個(gè)模塊。為什么要導(dǎo)入這個(gè)模塊呢?這個(gè)問題有點(diǎn)瞧不起大家了,因?yàn)槲覀兛赡苄枰褂眠@個(gè)模塊的某個(gè)功能。那在導(dǎo)入這個(gè)模塊的時(shí)候,Python解釋器需要做哪些工作呢?在使用一個(gè)類的時(shí)候,我們肯定是需要調(diào)用構(gòu)造函數(shù)來初始化的,導(dǎo)入模塊就類似于這樣的一個(gè)初始化過程。所以肯定會(huì)有一個(gè)初始化函數(shù),它長(zhǎng)啥樣?
在文檔中有這樣一句: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.
所以對(duì)于greenlet,我們就能找到initgreenlet(void)函數(shù)。
#define INITERROR return // 第一次導(dǎo)入greenlet模塊時(shí)調(diào)用 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; } ... }
首先根據(jù)模塊名查找相應(yīng)的初始化函數(shù),然后Py_InitModule()函數(shù)向Python解釋器注冊(cè)該模塊中所有可以用到的方法。而Py_InitModule()函數(shù)是由Python提供的C API,對(duì)于使用C API只需要包含一個(gè)頭文件就可以了。
官方文檔描述: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"方法列表
看下關(guān)鍵代碼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,在這個(gè)模塊中指的就是GreenMethods,一般稱它為方法列表。該列表給出了所有可以被Python解釋器使用的方法,將這些方法注冊(cè)到這個(gè)模塊中,這樣在我們導(dǎo)入模塊后就可以直接使用了。
當(dāng)Python程序第一次導(dǎo)入greenlet模塊的時(shí)候,調(diào)用initgreenlet()函數(shù)。接著Py_InitModule()會(huì)創(chuàng)建一個(gè)“模塊對(duì)象”(它將被插入到sys.modules字典下的“greenlet”鍵下),并且將方法列表(PyMethodDef結(jié)構(gòu)數(shù)組)構(gòu)成的內(nèi)建函數(shù)對(duì)象作為它的第二個(gè)參數(shù)傳到剛被創(chuàng)建的模塊中。Py_InitModule()返回一個(gè)指向它創(chuàng)建的模塊對(duì)象的指針。方法列表代碼:
static PyMethodDef GreenMethods[] = { {"getcurrent", (PyCFunction)mod_getcurrent, METH_NOARGS, /*XXX*/ NULL}, ... };
方法列表中的各項(xiàng)參數(shù)如下:
(PyCFunction)mod_getcurrent函數(shù)如下:
static PyObject* mod_getcurrent(PyObject* self) { if (!STATE_OK) return NULL; Py_INCREF(ts_current); return (PyObject*) ts_current; }
該函數(shù)的作用就是獲取當(dāng)前greenlet對(duì)象,并添加引用計(jì)數(shù)。
小結(jié)一個(gè)模塊的初始化工作大致是這樣的。不過針對(duì)greenlet發(fā)現(xiàn)了一些問題,在該模塊的方法列表中看到了getcurrent,而其他像switch、run等卻沒有看到。隨后去查閱greenlet的官方文檔,看到了greenlet.getcurrent()和g.switch(*args, **kwargs),卻被分別安排在『實(shí)例化』和『greenlets的方法和屬性』兩個(gè)不同的標(biāo)題之下,為什么要這樣區(qū)分呢?
以上部分都是一個(gè)Python C擴(kuò)展模塊基本的初始化工作,針對(duì)greenlet還有其他要做的。具體怎么做以及上面問題的答案就放到下一篇講吧,因?yàn)閮?nèi)容比較多在這篇講不完。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://www.ezyhdfw.cn/yun/37422.html
摘要:怎么記錄呢這里就可以回到上面我們需要了解的幾個(gè)棧操作了。這個(gè)時(shí)候,如果函數(shù)執(zhí)行完了想去執(zhí)行函數(shù)的時(shí)候,就按照這個(gè)流程再保存,然后再把剛才存放的函數(shù)給復(fù)制到棧中。 showImg(http://young-py.github.io/imgs/yyzt2.jpg); gevent文檔:that uses greenlet to provide a high-level synchrono...
摘要:一旦有事件產(chǎn)生可能是一次出現(xiàn)好多個(gè)事件,就會(huì)按照優(yōu)先級(jí)依次調(diào)用每個(gè)事件的回調(diào)函數(shù)。注意,是有超時(shí)的,所以一些無(wú)法以文件描述符的形式存在的事件也可以有機(jī)會(huì)被觸發(fā)。 這一篇主要想跟大家分享一下 Gevent 實(shí)現(xiàn)的基礎(chǔ)邏輯,也是有同學(xué)對(duì)這個(gè)很感興趣,所以貼出來跟大家一起分享一下。 Greenlet 我們知道 Gevent 是基于 Greenlet 實(shí)現(xiàn)的,greenlet 有的時(shí)候也被...
摘要:隨著我們對(duì)于效率的追求不斷提高,基于單線程來實(shí)現(xiàn)并發(fā)又成為一個(gè)新的課題,即只用一個(gè)主線程很明顯可利用的只有一個(gè)情況下實(shí)現(xiàn)并發(fā)。作為的補(bǔ)充可以檢測(cè)操作,在遇到操作的情況下才發(fā)生切換協(xié)程介紹協(xié)程是單線程下的并發(fā),又稱微線程,纖程。 引子 之前我們學(xué)習(xí)了線程、進(jìn)程的概念,了解了在操作系統(tǒng)中進(jìn)程是資源分配的最小單位,線程是CPU調(diào)度的最小單位。按道理來說我們已經(jīng)算是把cpu的利用率提高很多了。...
摘要:所以與多線程相比,線程的數(shù)量越多,協(xié)程性能的優(yōu)勢(shì)越明顯。值得一提的是,在此過程中,只有一個(gè)線程在執(zhí)行,因此這與多線程的概念是不一樣的。 真正有知識(shí)的人的成長(zhǎng)過程,就像麥穗的成長(zhǎng)過程:麥穗空的時(shí)候,麥子長(zhǎng)得很快,麥穗驕傲地高高昂起,但是,麥穗成熟飽滿時(shí),它們開始謙虛,垂下麥芒。 ——蒙田《蒙田隨筆全集》 上篇論述了關(guān)于python多線程是否是雞肋的問題,得到了一些網(wǎng)友的認(rèn)可,當(dāng)然也有...
摘要:協(xié)程,又稱微線程,纖程。最大的優(yōu)勢(shì)就是協(xié)程極高的執(zhí)行效率。生產(chǎn)者產(chǎn)出第條數(shù)據(jù)返回更新值更新消費(fèi)者正在調(diào)用第條數(shù)據(jù)查看當(dāng)前進(jìn)行的線程函數(shù)中有,返回值為生成器庫(kù)實(shí)現(xiàn)協(xié)程通過提供了對(duì)協(xié)程的基本支持,但是不完全。 協(xié)程,又稱微線程,纖程。英文名Coroutine協(xié)程看上去也是子程序,但執(zhí)行過程中,在子程序內(nèi)部可中斷,然后轉(zhuǎn)而執(zhí)行別的子程序,在適當(dāng)?shù)臅r(shí)候再返回來接著執(zhí)行。 最大的優(yōu)勢(shì)就是協(xié)程極高...
閱讀 2769·2021-11-24 10:44
閱讀 2150·2021-11-22 13:53
閱讀 2184·2021-09-30 09:47
閱讀 3845·2021-09-22 16:00
閱讀 2546·2021-09-08 09:36
閱讀 2386·2019-08-30 15:53
閱讀 2950·2019-08-30 15:48
閱讀 1119·2019-08-30 15:44