Thread
s和Greenlet
在交互式環境中具有不同的行爲。在某些情況下,主事件循環必須被破解。
Greenlet
來自gevent
模塊,它是python中的併發任務。它具有與Python(pthread)分開的內部上下文切換,併發性非常好(根據我的經驗)。 Greenlets的一些問題是,如果它們沒有被猴子修補,它們會阻止C系統調用和套接字交互(模塊位於gevent
)。
爲了讓greenlet正常工作,主事件循環需要打補丁......如果你在交互式環境中產生一個greenlet,它將不會切換上下文並執行,我忘記了我的頭頂如何修補主事件循環(稍後添加)。失敗的
例子:
In [1]: from gevent.greenlet import Greenlet
In [2]: def print_hi():
...: print 'hi'
...:
In [3]: print_hi()
hi
In [4]: g = Greenlet(print_hi)
In [5]: g.start()
編輯:
尋找一些在這個項目上的代碼後這裏是我們如何破解IPython的輸入鉤使用GEVENT
import sys
import select
import gevent
def stdin_ready():
infds, outfds, erfds = select.select([sys.stdin], [], [], 0)
if infds:
return True
else:
return False
def inputhook_gevent():
try:
while not stdin_ready():
gevent.sleep(0.001)
except KeyboardInterrupt:
pass
return 0
# install the gevent inputhook
from IPython.lib.inputhook import inputhook_manager
inputhook_manager.set_inputhook(inputhook_gevent)
inputhook_manager._current_gui = 'gevent'
# First import the embeddable shell class
from IPython.frontend.terminal.embed import InteractiveShellEmbed
修補示例:
In [6]: def say_hi():
...: print "hi"
...:
In [7]: g = gevent.greenlet.Greenlet(say_hi)
In [8]: g.start()
In [9]: hi <-- Cursor is here so it printed hi
我不認爲這些問題與SYS或OS將永遠是不同的,因爲Interative的對比兩個版本(腳本)在相同的上下文中運行。換句話說,如果你使用「python script.py」或「python -i」,從任何給定的目錄中,cwd,路徑和環境都是相同的。 –
當你說「在迭代模式」,你說的是運行「python -i」,還是你在談論通過IDLE運行?這兩者之間肯定存在一些差異。 –
好問題,布萊恩奧克利。在這個問題中,我正在考慮'python myscript.py'與'python -i'並手動輸入相同的命令。如果你對你的斷言充滿信心(cwd,路徑和環境將是相同的),我會編輯我的問題以刪除我的誤導性陳述。 – Andrew