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()