python虛擬機(jī)運(yùn)行的原理是什么?很多新手對(duì)此不是很清楚,為了幫助大家解決這個(gè)難題,下面小編將為大家詳細(xì)講解,有這方面需求的人可以來(lái)學(xué)習(xí)下,希望你能有所收獲。

十多年的尋烏網(wǎng)站建設(shè)經(jīng)驗(yàn),針對(duì)設(shè)計(jì)、前端、開(kāi)發(fā)、售后、文案、推廣等六對(duì)一服務(wù),響應(yīng)快,48小時(shí)及時(shí)工作處理。成都全網(wǎng)營(yíng)銷的優(yōu)勢(shì)是能夠根據(jù)用戶設(shè)備顯示端的尺寸不同,自動(dòng)調(diào)整尋烏建站的顯示方式,使網(wǎng)站能夠適用不同顯示終端,在瀏覽器中調(diào)整網(wǎng)站的寬度,無(wú)論在任何一種瀏覽器上瀏覽網(wǎng)站,都能展現(xiàn)優(yōu)雅布局與設(shè)計(jì),從而大程度地提升瀏覽體驗(yàn)。創(chuàng)新互聯(lián)建站從事“尋烏網(wǎng)站設(shè)計(jì)”,“尋烏網(wǎng)站推廣”以來(lái),每個(gè)客戶項(xiàng)目都認(rèn)真落實(shí)執(zhí)行。
一、過(guò)程概述
1、python先把代碼(.py文件)編譯成字節(jié)碼,交給字節(jié)碼虛擬機(jī),然后虛擬機(jī)會(huì)從編譯得到的PyCodeObject對(duì)象中一條一條執(zhí)行字節(jié)碼指令,并在當(dāng)前的上下文環(huán)境中執(zhí)行這條字節(jié)碼指令,從而完成程序的執(zhí)行。Python虛擬機(jī)實(shí)際上是在模擬操作中執(zhí)行文件的過(guò)程。PyCodeObject對(duì)象中包含了字節(jié)碼指令以及程序的所有靜態(tài)信息,但沒(méi)有包含程序運(yùn)行時(shí)的動(dòng)態(tài)信息——執(zhí)行環(huán)境(PyFrameObject)
2、字節(jié)碼在python虛擬機(jī)程序里對(duì)應(yīng)的是PyCodeObject對(duì)象;.pyc文件是字節(jié)碼在磁盤(pán)上的表現(xiàn)形式。
3、從整體上看:OS中執(zhí)行程序離不開(kāi)兩個(gè)概念:進(jìn)程和線程。python中模擬了這兩個(gè)概念,模擬進(jìn)程和線程的分別是PyInterpreterState和PyTreadState。即:每個(gè)PyThreadState都對(duì)應(yīng)著一個(gè)幀棧,python虛擬機(jī)在多個(gè)線程上切換。當(dāng)python虛擬機(jī)開(kāi)始執(zhí)行時(shí),它會(huì)先進(jìn)行一些初始化操作,最后進(jìn)入PyEval_EvalFramEx函數(shù),它的作用是不斷讀取編譯好的字節(jié)碼,并一條一條執(zhí)行,類似CPU執(zhí)行指令的過(guò)程。函數(shù)內(nèi)部主要是一個(gè)switch結(jié)構(gòu),根據(jù)字節(jié)碼的不同執(zhí)行不同的代碼。
二、關(guān)于.pyc文件
PyCodeObject對(duì)象的創(chuàng)建時(shí)機(jī)是模塊加載的時(shí)候,即import。
1、執(zhí)行 python test.py 會(huì)對(duì)test.py進(jìn)行編譯成字節(jié)碼并解釋執(zhí)行,但不會(huì)生成test.pyc
2、如果test.py中加載了其他模塊,如import urllib2,那么python會(huì)對(duì)urllib2.py進(jìn)行編譯成字節(jié)碼,生成urllib2.pyc,然后對(duì)字節(jié)碼解釋執(zhí)行。
3、如果想生成test.pyc,我們可以使用python內(nèi)置模塊py_compile來(lái)編譯。
也可以執(zhí)行命令 python -m test.py 這樣,就生成了test.pyc
4、加載模塊時(shí),如果同時(shí)存在.py和.pyc,python會(huì)使用.pyc運(yùn)行,如果.pyc的編譯時(shí)間早于.py的時(shí)間,則重新編譯.py,并更新.pyc文件。
三、關(guān)于PyCodeObject
Python代碼的編譯結(jié)果就是PyCodeObject對(duì)象,如下:
typedef struct {
PyObject_HEAD
int co_argcount; /* 位置參數(shù)個(gè)數(shù) */
int co_nlocals; /* 局部變量個(gè)數(shù) */
int co_stacksize; /* 棧大小 */
int co_flags;
PyObject *co_code; /* 字節(jié)碼指令序列 */
PyObject *co_consts; /* 所有常量集合 */
PyObject *co_names; /* 所有符號(hào)名稱集合 */
PyObject *co_varnames; /* 局部變量名稱集合 */
PyObject *co_freevars; /* 閉包用的變量名集合 */
PyObject *co_cellvars; /* 內(nèi)部嵌套函數(shù)引用的變量名集合 */
/* The rest doesn’t count for hash/cmp */
PyObject *co_filename; /* 代碼所在文件名 */
PyObject *co_name; /* 模塊名|函數(shù)名|類名 */
int co_firstlineno; /* 代碼塊在文件中的起始行號(hào) */
PyObject *co_lnotab; /* 字節(jié)碼指令和行號(hào)的對(duì)應(yīng)關(guān)系 */
void *co_zombieframe; /* for optimization only (see frameobject.c) */
} PyCodeObject;四、執(zhí)行字節(jié)碼
Python虛擬機(jī)的原理就是模擬可執(zhí)行程序再X86機(jī)器上的運(yùn)行
假如test.py用C語(yǔ)言來(lái)實(shí)現(xiàn),會(huì)是下面這個(gè)樣子:
const char *s = “hello”;
void func() {
printf(“%s\n”, s);
}
int main() {
func();
return 0;
}Python虛擬機(jī)的原理就是模擬上述行為。當(dāng)發(fā)生函數(shù)調(diào)用時(shí),創(chuàng)建新的棧幀,對(duì)應(yīng)Python的實(shí)現(xiàn)就是PyFrameObject對(duì)象。
PyFrameObject對(duì)象創(chuàng)建程序運(yùn)行時(shí)的動(dòng)態(tài)信息,即執(zhí)行環(huán)境,相關(guān)源碼大致如下:
typedef struct _frame{
PyObject_VAR_HEAD //"運(yùn)行時(shí)棧"的大小是不確定的
struct _frame *f_back; //執(zhí)行環(huán)境鏈上的前一個(gè)frame,很多個(gè)PyFrameObject連接起來(lái)形成執(zhí)行環(huán)境鏈表
PyCodeObject *f_code; //PyCodeObject 對(duì)象,這個(gè)frame就是這個(gè)PyCodeObject對(duì)象的上下文環(huán)境
PyObject *f_builtins; //builtin名字空間
PyObject *f_globals; //global名字空間
PyObject *f_locals; //local名字空間
PyObject **f_valuestack; //"運(yùn)行時(shí)棧"的棧底位置
PyObject **f_stacktop; //"運(yùn)行時(shí)棧"的棧頂位置
//...
int f_lasti; //上一條字節(jié)碼指令在f_code中的偏移位置
int f_lineno; //當(dāng)前字節(jié)碼對(duì)應(yīng)的源代碼行
//...
//動(dòng)態(tài)內(nèi)存,維護(hù)(局部變量+cell對(duì)象集合+free對(duì)象集合+運(yùn)行時(shí)棧)所需要的空間
PyObject *f_localsplus[1];
} PyFrameObject;每一個(gè) PyFrameObject對(duì)象都維護(hù)了一個(gè) PyCodeObject對(duì)象,這表明每一個(gè) PyFrameObject中的動(dòng)態(tài)內(nèi)存空間對(duì)象都和源代碼中的一段Code相對(duì)應(yīng)。
看完上述內(nèi)容是否對(duì)您有幫助呢?如果還想對(duì)相關(guān)知識(shí)有進(jìn)一步的了解或閱讀更多相關(guān)文章,請(qǐng)關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道,感謝您對(duì)創(chuàng)新互聯(lián)的支持。
當(dāng)前文章:python虛擬機(jī)運(yùn)行的原理是什么
當(dāng)前URL:http://chinadenli.net/article2/gdedic.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供企業(yè)建站、建站公司、電子商務(wù)、網(wǎng)站收錄、全網(wǎng)營(yíng)銷推廣、云服務(wù)器
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)