Python并发第一个结果结束等待尚未完成的结果
Python concurrency first result ends waiting for not yet done results
我想做的是Move on...在第一个True之后,不关心还没有完成I/O绑定的任务。在下面的例子中,two() 是第一个也是唯一一个 True 所以程序需要像这样执行:
Second
Move on..
不是:
Second
First
Third
Move on...
import concurrent.futures
import time
def one():
time.sleep(2)
print('First')
return False
def two():
time.sleep(1)
print('Second')
return True
def three():
time.sleep(4)
print('Third')
return False
tasks = [one, two, three]
with concurrent.futures.ThreadPoolExecutor(max_workers=3) as executor:
for t in range(len(tasks)):
executor.submit(tasks[t])
print('Move on...')
with
语句不是您想要的,因为它等待所有提交的作业完成。您需要提交任务,就像您已经做的那样,然后调用 as_completed
等待第一个 returns 为真(并且不再)的任务:
executor = concurrent.futures.ThreadPoolExecutor()
futures = [executor.submit(t) for t in tasks]
for f in concurrent.futures.as_completed(futures):
if f.result():
break
print('Move on...')
concurrent.futures.ThreadPoolExecutor
的问题是,一旦任务被提交,它们将 运行 完成,所以程序将打印 'Move on...' 但如果实际上没有别的事可做,程序不会终止,直到函数 one
和 three
终止并(并打印它们的消息)。所以程序保证运行至少4秒
最好使用 multiprocessing.pool
模块中的 ThreadPool
class,它支持 terminate
方法,可以终止所有未完成的任务。最接近 as_completed
方法的可能是使用 imap_unordered
方法,但这需要一个辅助函数用于所有 3 个任务。但是我们可以使用 apply_async
指定在结果可用时调用的回调函数:
from multiprocessing.pool import ThreadPool
import time
from threading import Event
def one():
time.sleep(2)
print('First')
return False
def two():
time.sleep(1)
print('Second')
return True
def three():
time.sleep(4)
print('Third')
return False
def my_callback(result):
if result:
executor.terminate() # kill all other tasks
done_event.set()
tasks = [one, two, three]
executor = ThreadPool(3)
done_event = Event()
for t in tasks:
executor.apply_async(t, callback=my_callback)
done_event.wait()
print("Moving on ...")
我想做的是Move on...在第一个True之后,不关心还没有完成I/O绑定的任务。在下面的例子中,two() 是第一个也是唯一一个 True 所以程序需要像这样执行:
Second
Move on..
不是:
Second
First
Third
Move on...
import concurrent.futures
import time
def one():
time.sleep(2)
print('First')
return False
def two():
time.sleep(1)
print('Second')
return True
def three():
time.sleep(4)
print('Third')
return False
tasks = [one, two, three]
with concurrent.futures.ThreadPoolExecutor(max_workers=3) as executor:
for t in range(len(tasks)):
executor.submit(tasks[t])
print('Move on...')
with
语句不是您想要的,因为它等待所有提交的作业完成。您需要提交任务,就像您已经做的那样,然后调用 as_completed
等待第一个 returns 为真(并且不再)的任务:
executor = concurrent.futures.ThreadPoolExecutor()
futures = [executor.submit(t) for t in tasks]
for f in concurrent.futures.as_completed(futures):
if f.result():
break
print('Move on...')
concurrent.futures.ThreadPoolExecutor
的问题是,一旦任务被提交,它们将 运行 完成,所以程序将打印 'Move on...' 但如果实际上没有别的事可做,程序不会终止,直到函数 one
和 three
终止并(并打印它们的消息)。所以程序保证运行至少4秒
最好使用 multiprocessing.pool
模块中的 ThreadPool
class,它支持 terminate
方法,可以终止所有未完成的任务。最接近 as_completed
方法的可能是使用 imap_unordered
方法,但这需要一个辅助函数用于所有 3 个任务。但是我们可以使用 apply_async
指定在结果可用时调用的回调函数:
from multiprocessing.pool import ThreadPool
import time
from threading import Event
def one():
time.sleep(2)
print('First')
return False
def two():
time.sleep(1)
print('Second')
return True
def three():
time.sleep(4)
print('Third')
return False
def my_callback(result):
if result:
executor.terminate() # kill all other tasks
done_event.set()
tasks = [one, two, three]
executor = ThreadPool(3)
done_event = Event()
for t in tasks:
executor.apply_async(t, callback=my_callback)
done_event.wait()
print("Moving on ...")