成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

我到Python虛擬機里逛了一圈,回來就被干掉了!

開發 開發工具 虛擬化
我出生在C盤一個很深的目錄下,也不知道是誰把我放到這里的。

 我出生在C盤一個很深的目錄下,也不知道是誰把我放到這里的。

[[284293]]

我無事可干,整天就是睡覺,睡醒了就和我的鄰居Account.class聊天,他曾經去過一次內存的Java虛擬機,不停地給我重復他的JVM奇遇記,什么陌生警察,什么虛擬機大樓,什么清理者,讓我聽得心癢癢的,也想來一次這樣的冒險。

他告訴我:冒險經歷的開端是兩個警察,你就等著他們來吧。

1

陌生警察

這一天我正在睡覺,突然咣咣有人砸我房門。

我打開門一看,一高一矮兩個陌生警察!我的冒險之旅要開場了。

“你們是ClassLoader吧?” 我想起了Account.class告訴我,會有個叫ClassLoader的警察來裝載。

“什么ClassLoader? 我們Python不玩Java那一套!” 兇神惡煞的矮個子警察遞上了工作證:“我是Python編譯器,現在奉命對你的住處進行檢查,有沒有私藏pyc文件?”

“pyc? 什么pyc?” 我感覺情節發展和Account.class說得明顯不符。

“別裝了你!” 他四處查看,沒一會兒,在一個叫做_pycache_的角落里拉出來一個叫做user.pyc的家伙,“敢說你沒有私藏文件?”

我真是驚呆了,我確實是user.py,這個pyc是什么時候藏在這里的。

“讓我檢查檢查,” Python編譯器拿著放大鏡開始查看pyc這個家伙的二進制數據,“嗯,Magic Number是3394,是我們Python3.7編譯出來的,不過從修改時間戳看,實在是太老了。”

Python編譯器剛說完,抽出手槍,砰的一聲,就把這個pyc該干掉了, 他把頭轉向我:“現在,我對你重新編譯。”

可憐的pyc,連個臺詞都來不及說,就消失在空氣中了。

“有個叫order.py 的文件 import了你,現在我們奉命帶你去內存編譯。” Python編譯器冷冰冰地說到。

我很驚奇:“我們Python不是解釋執行嗎,怎么還要編譯?”

“真是無知,我們Python有虛擬機,執行的是字節碼,是先編譯,再解釋執行!走,去內存編譯。”

兩個警察不允許我帶任何東西,便把我推上車,我們一起奔向內存。

2

打探消息

我覺得前途未卜,不會編譯完以后把我也干掉吧?不能坐以待斃,一定得多了解信息。

“警察大哥,你們是怎么找到我的?” 我小心地問那個高個警察。

高個兒警察還算和藹,揮了揮手中的一個本子:“我是Python解釋器,我們會根據本子上記錄的Python模塊搜索規則來查找,你看,先從程序運行的當前目錄找,然后從PYTHONPATH找,然后是python的安裝設置相關的默認路徑。”

“瞧瞧,” 他指著本子說,“你就在C:\users\andy\temp\python\這個目錄下。”

我心說這和Java的ClassPath差不多。

“原來如此,那為什么把那個pyc給槍斃了?” 我心里緊張,下意識地看了一眼開車的Python編譯器。

“編譯一次挺花費時間的,所以就把字節碼緩存到了pyc文件中,如果你的源碼沒有變化,下次就不用編譯,直接執行了。否則,那個pyc文件就沒用了。”

我長出一口氣,看來我的源碼有改動!

“咱們怎么不用ClassLoader呢,我聽說Java都是這么干的。”

“說來話長,” 高個兒警察很有耐心,“他們Java最早的時候有個非常先進的理念,代碼可以從網絡下載,在本地的JVM的執行, 但是你怎么知道網上的那些代碼有沒有危害?所以就搞了一個沙箱機制,ClassLoader也分了層,Java的核心類(如java.lang.String)只能由最上層的ClassLoader來裝載,防止別有用心的人寫個同名的核心類搞破壞。”

我點頭:“奧,我們Python沒有這樣的需求,拿到源文件,編譯后解釋執行,也就不需要復雜的Class Loader了。”

3

編譯

說話間,車子就開到了內存。

Python編譯器下車,把我的代碼通通搬到內存,然后是一系列讓人眼花繚亂的詞法分析,語言分析, 形成抽象語法樹,從抽象語法樹中形成字節碼,此處略去3000字不表。

終于,他在內存中把我變成了二進制的字節碼。

 

“這是什么鬼? ”

Python編譯器說:“這就是pyc啊,就是PyCodeObject,編譯一次累死人,我把這個PyCodeObject的對象保存到pyc文件中,下一次就不用編譯了。”

“我給你舉個例子,”高個的Python解釋器接口道,“在你的user.py中有這么一段代碼

def add(a,b):

c = a + b

print(c)

編譯成PyCodeObject以后大概是這個樣子:

 

(注:這里展示的只是一個片段,實際的PyCodeObject經常是一個復雜的嵌套接結構)

局部常量表中記錄的是局部變量a,b,c 。

符號表中記錄了程序引用的符號,如print等。

字節碼就是真正的指令了,這些指令會引用常量表和符號表。”

只是展示一個片段就這么復雜了,我懶得去看這么多的細節,心里想著按照Account.class的劇本,接下來就要去方法區了。

可是高個子的Python解釋器說:“我們這兒沒有方法區,Python的對象和數據結構都是保存在一個Heap中的,user.py,這是你的地址,你帶著PyCodeObject到那里去吧,一會兒就有線程聯系你了。”

4

執行

去Heap區的路上,我看到一隊全副武裝的士兵不停地在巡邏,時不時把一些對象拉出來,塞到車里,不用說,這些都是可怕的清理者。

我仔細觀察了一下,每個對象的頭上都有一個引用計數,如果被使用,計數就會增加,不用就會減少,如果變成零,對不起,那就危險了。

按照地址找到了格子間,我倆剛坐下來,桌子上的視頻電話就響了。

畫面中,我看到一個編號為0x7954的線程坐在一個明亮的CPU車間里,他的面前是一個工作臺,工作臺上有一個深桶(后來知道這叫做棧)和一排小格子,還有一個引人注目的大鎖,上面寫著“GIL”。

這個線程對我說:“我是線程0x7954,我們的老板Python解釋器讓我調用你的add函數,請把第一條指令給我說一下。”

我說:“c = a +b ”

“聽不懂,你得給我說字節碼。”

我恍然大悟,趕緊從PyCodeObject中的字節碼區域尋找:“LOAD_FAST 0 (a)”

0x7594從編號為0的格子中找到了數字10, 也就是add函數的參數a 的值,放入棧中

 

然后0x7594說:“下一條指令。”

“LOAD_FAST 1 (b)”

于是數字20被放入了棧中:

 

然后是:BINARY_ADD, 這應該是個加法操作。

0x7954迅速地把10,20都取出來,做了加法,把結果30放入棧中。

 

最后是 :STORE_FAST 2 (c)

于是0x7954取出30,放到了編號為2的格子中

 

看到這里, 我就明白了Account.class曾經說過JVM是個基于棧的虛擬機, 看來Python VM也是如此啊。

不過既然都是虛擬機,為什么這里執行兩個整數的加法操作(BINARY_ADD)會這么慢呢?

電話那頭的0x7954似乎看透了我的心思:“我最煩這個BINARY_ADD指令了,Python是動態類型語言,運行期才知道具體類型,比如這段代碼

s1 = "hello"

s2 = "world"

s = s1 + s2

編譯后,底層的指令也是BINARY_ADD, 所以在執行這個指令的時候,還需要做類型判斷,如果操作數是整數,就相加;如果操作數是字符串,就做連接;如果一個是整數,一個是字符串,還得做轉型,我容易嗎我!”

看來靜態類型也有好處,可以直接編譯成對應的字節碼,整數相加就是iadd,字符串連接是其他字節碼,在運行時就不用判斷參數類型了。

5

GIL

執行的時間長了,我對這些字節碼熟得都能背下來了,這里實在是無聊。

0x7954執行完一條STORE_FAST指令以后,居然停了下來,我心中大喜,Account.class告訴過我,一旦停下來,那就是程序員要調試了,他們的一秒是我們的十多天,將會有個漫長的假期。

但是沒有什么調試, 0x7954從工作臺上抱起GIL這個大鎖離開了CPU車間。

他對我說:“對不起,剛才Python解釋器說我已經運行了100個ticks,必須得放棄這個GIL的鎖,讓別的線程使用CPU車間了。”

我說:“不對啊,你這里有4個CPU車間(CPU core),你為什么不去別的車間執行?”

“沒辦法,這是老大規定的,不管有多少個CPU車間,只有搶到GIL鎖的哪個線程才能運行。”

“這么多線程在等待GIL,這么多CPU車間空著,一核有難,多核圍觀,浪費啊,浪費!” 我不由得痛心疾首。

不知道等了多久,0x7954又獲得了GIL鎖,進入CPU車間執行。

我注意到一個特點,字節碼中對print函數的調用特別特別多。

程序員們怎么不調試呢?快樂假期怎么還不來呢?

0x7954說:“碼農有兩類

1. 調試派,出了問題喜歡調試

2. 輸出派,不喜歡單步調試,喜歡通過print來輸出信息

3. 思考派,出了問題先在腦子中分析定位,然后再調試。

我看咱們這位Python程序員屬于第二種。”

這個程序員“去年”還調試Java呢,怎么到了Python這里就變成輸出派了?我很疑惑。

6

尾聲

代碼終于執行完了,整個世界都消失了,我又回到了硬盤,正如Account.class所說,像做了一場夢一樣。

user.pyc熱情地給我打招呼:“大哥回來了,你可千萬別再改動了,你一改動我就完蛋。”

我說:“我也不想改,一改我也活不成, 但是我也控制不了程序員啊......”

話還沒說完,就感覺頭上遭遇了一記暴擊,我知道程序員動了我的源碼,也許是修改了一個Bug,我知道自己要被新版本覆蓋了。

user.pyc喃喃自語:“完了,這么快就改了.....”

這時候門外又響起了敲門聲......

【本文為51CTO專欄作者“劉欣”的原創稿件,轉載請通過作者微信公眾號coderising獲取授權】

 

戳這里,看該作者更多好文

 

責任編輯:武曉燕 來源: 51CTO專欄
相關推薦

2020-04-09 08:29:50

編程語言事件驅動

2015-11-02 14:40:00

數據挖掘定位

2014-02-21 11:20:34

KVMXen虛擬機

2020-11-09 14:03:51

Spring BootMaven遷移

2012-05-18 10:22:23

2020-07-21 08:06:05

日志

2013-07-17 09:32:58

2010-07-26 09:02:38

2011-06-28 17:13:46

Qt Designer UI

2011-06-30 11:07:02

Qt QTextEdit

2010-02-24 10:39:28

Python虛擬機

2010-05-27 10:19:47

2010-02-26 15:28:15

Python虛擬機

2014-12-18 09:41:44

虛擬化遷移

2009-08-28 11:54:27

VMware虛擬機

2025-05-13 07:02:43

2010-12-23 14:05:12

虛擬機

2012-04-10 10:29:29

2023-09-03 17:05:20

虛擬機

2020-01-17 10:52:37

無服務器容器技術
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 羞羞的视频网站 | 国产欧美在线播放 | 久久美女视频 | 麻豆久久精品 | 精品欧美乱码久久久久久1区2区 | 亚洲天堂久久 | 秋霞电影一区二区 | 亚洲一区在线免费观看 | 久久在线| 精品丝袜在线 | 久久久久电影 | 在线免费黄色小视频 | av香港经典三级级 在线 | 日本免费在线观看视频 | av一区二区在线观看 | 国产免费av在线 | 欧美成人精品一区二区三区 | 男人的天堂中文字幕 | 秋霞av国产精品一区 | 亚洲国产精品人人爽夜夜爽 | 欧美国产激情二区三区 | 91精品久久 | 三级黄色大片网站 | 日韩欧美久久精品 | 欧美一区二区三区视频 | av免费在线观看网站 | av黄色在线 | 最新高清无码专区 | 国产小视频在线 | 成人精品鲁一区一区二区 | 亚洲午夜小视频 | 日韩国产一区二区 | 欧美成人激情 | 日韩成人免费av | 黄色三级在线播放 | 毛片免费观看视频 | 成人精品一区二区三区中文字幕 | 久久99精品视频 | 亚洲成人三区 | 二区高清| 久久久久久国产精品久久 |