簡體   English   中英

實施虛擬線程而不作弊

[英]Implementing virtual threads without cheating

gevent教程中有一個如下所示的示例:

import gevent

def foo():
    print('Running in foo')
    gevent.sleep(0)
    print('Explicit context switch to foo again')

def bar():
    print('Explicit context to bar')
    gevent.sleep(0)
    print('Implicit context switch back to bar')

gevent.joinall([
    gevent.spawn(foo),
    gevent.spawn(bar),
])

而輸出是

Running in foo
Explicit context to bar
Explicit context switch to foo again
Implicit context switch back to bar

我測試了它,並親眼看到它的工作原理。 我的一位朋友聲稱這完全在一個線程內運行。 除了我不能想到gevent.sleep(0)的任何實現,它不能歸結為某種形式的“作弊”(即:交換前兩個堆棧幀等)

誰能解釋一下這是如何工作的? 如果這是Java(或至少某種禁止這種堆棧操作的語言),這可能嗎? (再次,不使用多個線程)。

它確實只在1個線程上運行。 gevent使用greenlets,它們是協程,而不是線程。 每個給定時間只有1個堆棧(除非您使用多線程,然后在每個線程中使用greenlet)。

在上面的示例中,無論何時調用sleep或joinall,當前的協程(greenlet)實際上都會向hub發送。 將集線器視為中央調度員,負責決定下一步將運行哪個協同程序。

為了說服自己,刪除gevent.sleep(0)調用,你會發現它的行為不同。

請注意,與線程不同,執行是確定性的,因此如果您運行程序兩次,它將以完全相同的順序執行。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM