摘要:以及和這是操作的。而且要特別注意的含義是把棧頂的值標識為,使得可以使用,所以還不是簡單地把恢復就可以了這篇博客把的內部狀態講得非常清楚以上可以解釋為什么沒有人在里搞字節碼的了,因為這個太{{BANNED}}。
kilim在JVM上實現了協程,其實現看起來挺容易的:http://www.malhar.net/sriram/kilim/thread_of_ones_own.pdf
在cPython上是否能夠復制其技法呢?粗看上去,是很容易的,甚至比JVM更好實現:
利用sys._getframe(0)可以獲得call stack上的任意frame
frame的f_locals可以獲得這個frame的所有局部變量的值(https://docs.python.org/3/library/inspect.html)
雖然python不支持goto或者longjmp,然后cPython的bytecode是支持JUMP_ABSOLUTE的(https://docs.python.org/3/library/dis.html)
一個更加牛B的事情是,有人已經用@goto裝飾器的方式在Python上實現了GOTO了
這個是Python 2版本的:http://code.activestate.com/recipes/576944-the-goto-decorator/
這個是Python 3版本的:https://github.com/cdjc/goto
這兩個實現很好的展示了如何在Python中做類似JVM上ASM庫做的事情,字節碼增強。
===============
但是,cPython的VM對于frame狀態的建模使得在cPython上實現kilim,比JVM要難得多。在cPython某個指令執行的那一刻,有五個部分的狀態
builtins
globals
locals
value_stack
block_stack
前三個都是python里做動態執行的常客,沒啥困難的。而且frame通過inpsect可以很輕易的獲得locals的值。而后兩者是非常困難的,我們可以來看一段我隨便寫的代碼
for i in range(1): print(i)
生成的bytecode是
0 SETUP_LOOP 30 (to 33) 3 LOAD_GLOBAL 0 (0) 6 LOAD_CONST 1 (1) 9 CALL_FUNCTION 1 (1 positional, 0 keyword pair) 12 GET_ITER >> 13 FOR_ITER 16 (to 32) 16 STORE_FAST 0 (0) 19 LOAD_GLOBAL 1 (1) 22 LOAD_FAST 0 (0) 25 CALL_FUNCTION 1 (1 positional, 0 keyword pair) 28 POP_TOP 29 JUMP_ABSOLUTE 13 >> 32 POP_BLOCK >> 33 LOAD_CONST 0 (0) 36 RETURN_VALUE
我們可以看到一個簡單的循環,產生了一對SETUP_LOOP和POP_BLOCK,這個是操作block_stack的。以及GET_ITER和FOR_ITER這是操作value_stack的。如果我們想要直接跳入到print(i)這一行,那么就要恢復當時的block_stack,以及當時的value_stack。而且要特別注意GET_ITER的含義是把棧頂的值標識為ITER,使得FOR_ITER可以使用,所以還不是簡單地把value_stack恢復就可以了
GET_ITER Implements TOS = iter(TOS).
這篇博客把python的frame內部狀態講得非常清楚:http://tech.blog.aknin.name/tag/block-stack/
以上可以解釋為什么沒有人在python里搞字節碼的trick了,因為這個VM太{{BANNED}}。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/37398.html
摘要:特別是最火的協程框架也無法保存狀態,讓人非常惋惜。但是因為棧的本身無法持久化,所以也就無法持久化。其難度在于,假設整個要持久化的調用棧全部都是內的,比如純的。采取的是暴力地把整個棧區域拷貝到上的方式來保存其狀態。 python主流的協程實現有五種: cPython的generator cPython的greenlet cPython的fibers stackless python ...
摘要:很長一段時間,我都很天真的認為,特別是以為代表的庫,才是協程的樂土。里是沒法實現協程,更別說實現這樣可以的協程的。咱真的是太井底之蛙了。不完全列表如下還有一個據作者說是最的這些協程庫的實現方式都是類似的,都是通過字節碼生成達到的目的。 很長一段時間,我都很天真的認為python,特別是以gevent為代表的庫,才是協程的樂土。Java里是沒法實現協程,更別說實現stackless py...
摘要:協程完全有用戶態程序控制,所以也被成為用戶態的線程。目前支持協程的語言有很多,例如等。協程之旅前篇結束,下一篇文章我們將深入分析原生協程部分的實現。 寫在最前 ??Swoole協程經歷了幾個里程碑,我們需要在前進的道路上不斷總結與回顧自己的發展歷程,正所謂溫故而知新,本系列文章將分為協程之旅前、中、后三篇。 前篇主要介紹協程的概念和Swoole幾個版本協程實現的主要方案技術; 中篇主...
摘要:問題為了防止銷毀時異步任務仍然在進行所導致的內存泄露,我們都會在方法中去取消異步任務。總結層可以天然自動監視銷毀,我一直在找尋如何優雅的自動取消異步任務,在目前來看是最佳的方案。協程絕對是最先進的,效率最高,最優雅的技術棧組合。前提 在Android MVVM模式,我使用了Jetpack包中的ViewModel來實現業務層,當然你也可以使用DataBinding,關于Android業務層架構...
閱讀 3917·2021-09-09 09:33
閱讀 1773·2021-09-06 15:14
閱讀 1919·2019-08-30 15:44
閱讀 3075·2019-08-29 18:36
閱讀 3765·2019-08-29 16:22
閱讀 2095·2019-08-29 16:21
閱讀 2530·2019-08-29 15:42
閱讀 1648·2019-08-29 11:00