2017-10-19 215 views
1

我想我得到這個錯誤是因爲我的代碼調用asyncio.get_event_loop().run_until_complete(foo())兩次。一旦從foo()第二次從函數調用foo()。那麼我的問題是:爲什麼這會成爲一個問題呢?爲什麼我更關心這個循環是否正在運行?RuntimeError:這個事件循環已經在Python中運行了


有這個問題,我認爲它,做編輯,遮蔽它(有些人喜歡遵守規則不理解他們,從而從標題刪除「非法」二字)。不幸的是,這造成了混亂。

我對提出錯誤的事實並不感到驚訝。我可以追溯到asyncio的來源,並看到這個圖書館的作者想這樣做,那裏沒有神祕的東西。令人困惑的是,圖書館的作者認爲,當循環已經運行時,要求事件循環運行一些函數以完成是非法的。

我們可以減少這個問題,只留下兩個這樣的電話,並通過案例分析,我們會發現這些都是三種可能性:

  1. 既不兩種功能永遠終止。
  2. 其中一個函數最終終止。
  3. 這兩個函數最終都會終止。

現在,是否有任何適合所有三種情況的理智行爲?對我而言,顯而易見的是,在這裏可能存在或者可能有多種理智的行爲。例如:

  1. 沒什麼特別的,兩個函數的執行都是交錯的,並且它們一直保持運行,就像預期的一樣。
  2. 以下的run_until_complete()第一個實例,直到第二函數完成(因此run_until_complete()後無代碼將被執行的環路不控制返回給代碼。
  3. 最後函數終止之後,循環將控制返回給所述第一代碼對象,調用run_until_complete忽略其他所有調用站點。

現在,我可以理解這種行爲可能不是東西,每個人都想要的。但是,因爲該庫決定給程序員控制起動/停止事件循環,它也應該能夠滿足這些決定的後果多次循環排除了庫代碼永遠不會這樣做,這降低了利用asyncio(這確實是例如aiohttp)的庫的質量和實用性。

回答

2

事件循環運行 - 是異步程序的入口點。它管理所有協程,任務和回調的運行。在運行循環時沒有任何意義:在某種程度上,就像試圖從同一個已經運行的作業執行程序運行作業執行程序一樣。

既然你有這個問題,我想你可能會誤解asyncio的工作方式。請閱讀this article - 這不是很大,並給出了一個很好的介紹。

UPD:

有中添加多的東西,而這個循環已經運行到被事件循環運行絕對沒有問題。你可以只用等待它做到這一點:

await coro() # add coro() to be run by event loop blocking flow here until coro() is finished 

或創建任務:

asyncio.ensure_future(coro()) # add coro() to be run by event loop without blocking flow here 

正如你可以看到你不需要調用事件循環的方法,使一些被它跑了。

事件循環的方法,如run_foreverrun_until_complete - 只是一種啓動事件循環的方法。

run_until_complete(foo())意思是:「添加foo()由事件循環運行並運行事件循環本身直到foo()未完成」。

+0

...但我沒有運行事件循環,我運行'foo()'爲什麼我甚至不得不明確運行循環?誰會在地球上想要*那*?這就像用你的雙手移動你的掛鐘的手...讓時間前進... – wvxvw

+0

重新'文章 - 謝謝你。我現在會讀它。與任何將併發功能融入其設計的語言相比,「asyncio」在很多層面上都非常糟糕,以至於無法兌換。一切都很糟糕,設計,實現和文檔...... Python總體來說是一種體面的語言,但是這個補充......我甚至不知道如何描述它。 – wvxvw

+0

那麼,這篇文章是非常膚淺的,與夫婦你好 - 世界一級的例子,當應用到更現實的東西時不保水...:/ – wvxvw

相關問題