[英]Running a script through subprocess hangs when script runs an asyncio eventloop inside multiprocessing workers
在Windows上運行Python 3.7.3,
我有一種情況, asyncio
事件循環永遠不會從多處理產生的進程中產生。 我無法顯示所有代碼,但它是這樣的:
multiprocessing
來加速使用第三方API的查詢。 thirdparty.api
支持服務器 - 客戶端體系結構,並在內部使用asyncio事件循環。 它在一個單獨的線程中運行一個事件循環; 在該線程中,它調用event_loop.run_forever()
並僅在KeyboardInterrupt
上調用。 subprocess
進程從另一個Py27腳本運行此腳本。 在我的多處理工作進程中,如果查詢失敗,則調用永遠不會返回,並且它無法自然地突破工作進程,即使是通用異常處理程序也不會捕獲任何內容並且會卡住。 我的調用者腳本的代碼片段:
#!/usr/bin/env python2
def main()
try:
cmd = ['C:\\Python\\Python37\\pythonw.exe', 'worker.py']
print(' '.join(cmd))
proc = subprocess.Popen(cmd, shell=False, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
out, err = proc.communicate()
except subprocess.CalledProcessError as err:
print(err)
except Exception:
traceback.print_exc()
else:
print('try popen finished with else.')
print('stdout: {}'.format(out))
print('stderr: {}'.format(err))
if __name__ == '__main__':
main()
我的worker worker.py
函數的偽代碼片段如下所示:
#!/usr/bin/env python3
args = [
...
]
def worker(*mpargs):
with thirdparty.api() as myclient:
try:
myclient.query(*args)
except Exception:
traceback.print_exc()
def exception_worker(*mpargs)
raise RuntimeError('Making trouble!')
def main():
logging.info('STARTED!')
with multiprocessing.Pool(processes=multiprocessing.cpu_count()) as pool:
results = pool.map(worker, args)
# results = pool.map(exception_worker, args)
pool.close()
pool.join()
logging.info('ALL DONE!')
if __name__ == '__main__':
main()
thirdparty.api在其構造函數中啟動事件循環:
self.loop = asyncio.get_event_loop()
if self.loop.is_closed():
self.loop = asyncio.new_event_loop()
asyncio.set_event_loop(self.loop)
然后在其單獨的線程中:
try:
self._loop.run_forever()
except KeyboardInterrupt:
pass
self.loop.close()
我已經嘗試了另一個工作者exception_worker
,它只拋出異常,並且這個返回沒有問題。
我該怎么解決這個問題?
在詳細說明問題后,我終於在這篇文章中找到了解決方案: 為什么我在Windows上使用async和await獲取NotImplementedError?
thirdparty.api
需要關注這個細節,在修復之后,我的問題就消失了。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.