Python 在默认执行器中的任务仍在运行时退出程序
我有一个程序,它执行一些长时间运行的同步任务,并且可能需要退出,即使其中一些任务尚未完成。以下是在Python 在默认执行器中的任务仍在运行时退出程序,python,multithreading,python-asyncio,Python,Multithreading,Python Asyncio,我有一个程序,它执行一些长时间运行的同步任务,并且可能需要退出,即使其中一些任务尚未完成。以下是在main()中启动此任务的简单程序main()之后立即返回,因此程序应该退出 import asyncio, time def synchronous_task(): for i in range(5): print(i) time.sleep(1) async def main(): loop.run_in_executor(None, sync
main()
中启动此任务的简单程序main()
之后立即返回,因此程序应该退出
import asyncio, time
def synchronous_task():
for i in range(5):
print(i)
time.sleep(1)
async def main():
loop.run_in_executor(None, synchronous_task)
loop = asyncio.get_event_loop()
loop.run_until_complete(main())
print('Main thread exiting.')
但我在运行脚本时得到了以下结果:
$ python3.5 test3.py
0
Main thread exiting.
1
2
3
4
如何处理这种情况?事件循环的默认执行器已经使用了守护进程线程,在我的情况下,在没有清理的情况下终止程序是可以的,但我不想使用
os.\u exit()
关于如何杀死线程的更多问题。详细信息请查看帖子
事件的解决方案是:
import asyncio, time
from functools import partial
import threading
import concurrent
def synchronous_task(ev):
for i in range(5):
if ev.isSet():
print('terminating thread')
return
print(i)
time.sleep(1)
async def main():
ev = threading.Event() # see: https://stackoverflow.com/a/325528/1113207
loop.run_in_executor(None, partial(synchronous_task, ev))
await asyncio.sleep(2) # give thread some time to execute, to see results
ev.set()
loop = asyncio.get_event_loop()
executor = concurrent.futures.ThreadPoolExecutor(5)
loop.set_default_executor(executor)
try:
loop.run_until_complete(main())
finally:
loop.run_until_complete(loop.shutdown_asyncgens())
executor.shutdown(wait=True) # see: https://stackoverflow.com/a/32615276/1113207
loop.close()
print('Main thread exiting.')
结果:
0
1
terminating thread
Main thread exiting.
[Finished in 2.2s]
你的问题更多的是关于如何杀死线程。详细信息请查看帖子 事件的解决方案是:
import asyncio, time
from functools import partial
import threading
import concurrent
def synchronous_task(ev):
for i in range(5):
if ev.isSet():
print('terminating thread')
return
print(i)
time.sleep(1)
async def main():
ev = threading.Event() # see: https://stackoverflow.com/a/325528/1113207
loop.run_in_executor(None, partial(synchronous_task, ev))
await asyncio.sleep(2) # give thread some time to execute, to see results
ev.set()
loop = asyncio.get_event_loop()
executor = concurrent.futures.ThreadPoolExecutor(5)
loop.set_default_executor(executor)
try:
loop.run_until_complete(main())
finally:
loop.run_until_complete(loop.shutdown_asyncgens())
executor.shutdown(wait=True) # see: https://stackoverflow.com/a/32615276/1113207
loop.close()
print('Main thread exiting.')
结果:
0
1
terminating thread
Main thread exiting.
[Finished in 2.2s]
你让主线程退出,这不是你想要的吗?@stovfl不,我想进程终止。但正如您所看到的,它在主线程退出后继续打印到控制台。您希望
终止/杀死同步任务。您是否尝试过loop.close()
?您将退出主线程,这不是您想要的吗?@stovfl否,我希望进程终止。但正如您所看到的,它在主线程退出后继续打印到控制台。您希望终止/杀死同步任务。您是否尝试过loop.close()
?谢谢您的回答。我最初的问题不是关于如何突然终止单个线程,然后我将使用子进程。它是关于如何在线程仍在运行时终止整个进程。也许我的问题写得不够清楚。与此同时,我实际上实施了与你的建议类似的东西。我将编写ev.wait(1)
并删除对time.sleep()
的调用,而不是ev.isSet()
。谢谢您的回答。我最初的问题不是关于如何突然终止单个线程,然后我将使用子进程。它是关于如何在线程仍在运行时终止整个进程。也许我的问题写得不够清楚。与此同时,我实际上实施了与你的建议类似的东西。我将编写ev.wait(1)
并删除对time.sleep()的调用,而不是ev.isSet()
。