python原始碼分析筆記 2

2021-09-25 00:00:26 字數 2501 閱讀 3869

一.python中的整數物件

1.首先補充一下c語言知識的盲點,python底層都是用c寫的,看的時候發現自己還是有**看不懂,所有就先複習一下這些知識點。

先說明 c語言中register關鍵字的作用

register修飾符暗示編譯程式相應的變數將被頻繁地使用,如果可能的話,應將其儲存在cpu的暫存器中,以加快其儲存速度。例如下面的記憶體塊拷貝**

還有就是關於引數巨集的一些用法,之前c大學學的都是無參巨集,這兩者雖然在原理上是一樣的,但是有參巨集其中的陷阱比較多。

巨集定義的缺點:

由於是直接嵌入的,所以**可能相對多一點;

巢狀定義過多可能會影響程式的可讀性,而且很容易出錯,不容易除錯。

對帶參的巨集而言,由於是直接替換,並不會檢查引數是否合法,存在安全隱患。

2.小整數物件,物件池

實際的程式設計中,數值比較小的整數,比如1,2,29可能在程式中會非常頻繁的使用,但是由於python的特性,這些小整數物件都在堆上,要不斷的malloc,free會很浪費效能。所以使用了物件池技術。那什麼叫小整數呢,這個可以由寫**的你自己決定。但是非常麻煩,你需要去修改python的源**。在python原始碼中

#ifndef nsmallposints

#define nsmallposints 257

#endif

#ifndef nsmallposints

#define nsmallnegints 5

#endif

#if nsmallnegints + nsmallposints >0

static pyobject *small_ints[nsmallnegints + nsmallposints]

#endif

small_ints就是物件池,或者說 pyintobject池。在python 2.5中,將小整數集的範圍預設設定為 (-5,257)。對於小整數集會存放在記憶體中,並將其指標存放於small_ints中。

3.大整數物件

python會提供一塊記憶體空間供大整數物件輪流使用,也就是說誰需要的時候就用誰。在python中,有乙個pyintblock結構,在這個結構的基礎上,實現了的乙個單向列表。

#define block_size 100

#define bhead_size 8

#define n_intobjects ((block_size-bheadsize) / sizeof(pyintobject))

struct _intblock (

struct _intblock *next;

pyintobject object[n_intobjects];

);typedf struct _intblock pyintblock;

static pyintblock *block_list =null

static pyintobject *free_list =null

這段**的意思就是結構裡維護了一塊記憶體(block),其中儲存了一些pyintobject物件。從pyintblock的定義中可以看到,維護著n_intobjects個物件,當然這裡的值我們也可以修改python的源**去改變這個值。pyintblock的單向列表由block_list維護,每乙個block都維護乙個pyintobject物件的記憶體。而free_list則維護全部block的空閒記憶體。

4.整數物件的銷毀

static void int_dealloc(pyintobject *v)

( if (pyint_checkexact(v))

else

v->obtype->tp_free((pyobject *)v);

由block_list維護的pyintblock鍊錶中的記憶體實際是所有的大整數物件共同分享的。當乙個pyintobject物件被銷毀時,它所佔的記憶體並不會被釋放,歸還給系統,python會繼續保留著。將來提供給別的pyintobject使用,所以python應該將其鏈入了free_list所維護的自由記憶體鍊錶。 【注】: 實線是block_list, 虛線是free_list

由於python記憶體共享,python用於實現該物件池的記憶體與歷史上建立的整數物件的個數無關,而僅僅與同一時刻共存的的整數物件個數的最大值有關。

5.小整數物件池的初始化

現在只剩下最後乙個問題了,在small_ints中,它維護的只是pyintobject指標,那這些小整數物件是什麼時候被建立和初始化的呢,完成這一系列的操作正是_pyint_init

int _pyint_init(void)

python原始碼剖析 筆記2

pystringobject物件 typedef struct pystringobject 頭部儲存乙個ob size,表示字串在記憶體中的具體長度,字串由ob sval指標指向,但是,字串的最後一位也一定是 0 結束,由於有ob size的標記,允許字串中間也有 0 字元的存在。字串的型別物件中...

iptables原始碼分析(2)

1.1 表的查詢 再回到iptc init 函式上來,它根據表名,從核心獲取對應的表的相關資訊,handle是乙個iptc handle t型別的指標,在libiptc.c中,有如下定義 transparent handle type.typedef struct iptc handle iptc ...

Leveldb原始碼分析 2

輕鬆一刻,前面約定中講過leveldb使用了很多varint型編碼,典型的如後面將涉及到的各種key。其中的編碼 解碼函式分為varint和fixedint兩種。int32和int64操作都是類似的。首先是fixedint編碼,直接上 很簡單明瞭。void encodefixed32 char bu...