concurrent.futures.ThreadPoolExecutor() 为什么线程在转到下一行之前等待完成?
concurrent.futures.ThreadPoolExecutor() why threads wait for completion before going to next line?
尝试下面的代码。
import concurrent.futures
import time
def do_it():
with concurrent.futures.ThreadPoolExecutor() as my_executor:
t1 = my_executor.submit(doing, 3)
ret_value = t1.result()
t2 = my_executor.submit(some_func)
return f"doing return is {ret_value}"
def doing(num):
print(f"Calculating Square for {num}")
return num*num
def some_func():
print("sleep for 6 sec")
time.sleep(6)
print("done sleeping 6 secs")
start = time.perf_counter()
print(do_it())
finish = time.perf_counter()
print(f"total time {finish-start}")
低于输出:
Calculating Square for 3
sleep for 6 sec
done sleeping 6 secs
doing return is 9
total time 6.0060749100002795
但我期待(并且想要):
Calculating Square for 3
sleep for 6 sec
doing return is 9
total time <time much much less than 6>
<then after 6 sec>
done sleeping 6 secs
我想要 t1 Asap 的 return 值,让 t2 继续。我怎样才能实现它。感谢您的帮助。
你在这里写了什么:
t1 = my_executor.submit(doing, 3)
ret_value = t1.result()
t2 = my_executor.submit(some_func)
使两个函数(doing
和 some_func
)按顺序 运行ning 而不是并发,因为您使用 .result()
显式阻塞并等待第一个函数的值在启动第二个之前。
如果你想同时运行这两个函数,那么你必须在等待它们之前提交它们:
def do_it():
with concurrent.futures.ThreadPoolExecutor() as my_executor:
t1 = my_executor.submit(doing, 3)
t2 = my_executor.submit(some_func)
ret_value = t1.result()
return f"doing return is {ret_value}"
这里,t1
和t2
运行并发,他们(几乎)同时提交。然后你等待 t1
通过 .result()
的结果和 return 它的值,这就是你可能想要的。
但是,如果您需要等待两个函数之间的第一个可用结果,您可以使用 wait
函数或 as_completed
函数,看看 documentation学习如何使用它们。
编辑
with
语句打开一个上下文管理器,在继续之前调用执行器的.shutdown()
。此方法在 returning 之前等待所有期货完成,因此当 t1 和 t2 完成时 do_it()
仅 returns。
如果你想returnt2一启动,将executor作为参数传递,避免在这个函数中调用.shutdown()
:
import concurrent.futures
import time
def do_it(executor):
ret_value = doing(3)
t2 = executor.submit(some_func)
return f"doing return is {ret_value}"
def doing(num):
print(f"Calculating Square for {num}")
return num*num
def some_func():
print("sleep for 6 sec")
time.sleep(6)
print("done sleeping 6 secs")
with concurrent.futures.ThreadPoolExecutor() as executor:
start = time.perf_counter()
print(do_it(executor))
finish = time.perf_counter()
print(f"total time {finish-start}")
你说t2需要t1的值,所以那些调用不能并发,你可以串行执行t1。
另外请注意,在 t1 完成后立即在 do_it
函数内提交 t2 并没有实际意义。你可以提交 t2 after do_it
has returned,这更符合逻辑也更简单:
import concurrent.futures
import time
def do_it():
ret_value = doing(3)
return f"doing return is {ret_value}"
def doing(num):
print(f"Calculating Square for {num}")
return num*num
def some_func():
print("sleep for 6 sec")
time.sleep(6)
print("done sleeping 6 secs")
with concurrent.futures.ThreadPoolExecutor() as executor:
start = time.perf_counter()
print(do_it())
executor.submit(some_func)
finish = time.perf_counter()
print(f"total time {finish-start}")
这并没有给出你想要的确切输出(两个打印语句交错),但这无关紧要,结果是一样的,t2 在 t1 完成后立即启动。
尝试下面的代码。
import concurrent.futures
import time
def do_it():
with concurrent.futures.ThreadPoolExecutor() as my_executor:
t1 = my_executor.submit(doing, 3)
ret_value = t1.result()
t2 = my_executor.submit(some_func)
return f"doing return is {ret_value}"
def doing(num):
print(f"Calculating Square for {num}")
return num*num
def some_func():
print("sleep for 6 sec")
time.sleep(6)
print("done sleeping 6 secs")
start = time.perf_counter()
print(do_it())
finish = time.perf_counter()
print(f"total time {finish-start}")
低于输出:
Calculating Square for 3
sleep for 6 sec
done sleeping 6 secs
doing return is 9
total time 6.0060749100002795
但我期待(并且想要):
Calculating Square for 3
sleep for 6 sec
doing return is 9
total time <time much much less than 6>
<then after 6 sec>
done sleeping 6 secs
我想要 t1 Asap 的 return 值,让 t2 继续。我怎样才能实现它。感谢您的帮助。
你在这里写了什么:
t1 = my_executor.submit(doing, 3)
ret_value = t1.result()
t2 = my_executor.submit(some_func)
使两个函数(doing
和 some_func
)按顺序 运行ning 而不是并发,因为您使用 .result()
显式阻塞并等待第一个函数的值在启动第二个之前。
如果你想同时运行这两个函数,那么你必须在等待它们之前提交它们:
def do_it():
with concurrent.futures.ThreadPoolExecutor() as my_executor:
t1 = my_executor.submit(doing, 3)
t2 = my_executor.submit(some_func)
ret_value = t1.result()
return f"doing return is {ret_value}"
这里,t1
和t2
运行并发,他们(几乎)同时提交。然后你等待 t1
通过 .result()
的结果和 return 它的值,这就是你可能想要的。
但是,如果您需要等待两个函数之间的第一个可用结果,您可以使用 wait
函数或 as_completed
函数,看看 documentation学习如何使用它们。
编辑
with
语句打开一个上下文管理器,在继续之前调用执行器的.shutdown()
。此方法在 returning 之前等待所有期货完成,因此当 t1 和 t2 完成时 do_it()
仅 returns。
如果你想returnt2一启动,将executor作为参数传递,避免在这个函数中调用.shutdown()
:
import concurrent.futures
import time
def do_it(executor):
ret_value = doing(3)
t2 = executor.submit(some_func)
return f"doing return is {ret_value}"
def doing(num):
print(f"Calculating Square for {num}")
return num*num
def some_func():
print("sleep for 6 sec")
time.sleep(6)
print("done sleeping 6 secs")
with concurrent.futures.ThreadPoolExecutor() as executor:
start = time.perf_counter()
print(do_it(executor))
finish = time.perf_counter()
print(f"total time {finish-start}")
你说t2需要t1的值,所以那些调用不能并发,你可以串行执行t1。
另外请注意,在 t1 完成后立即在 do_it
函数内提交 t2 并没有实际意义。你可以提交 t2 after do_it
has returned,这更符合逻辑也更简单:
import concurrent.futures
import time
def do_it():
ret_value = doing(3)
return f"doing return is {ret_value}"
def doing(num):
print(f"Calculating Square for {num}")
return num*num
def some_func():
print("sleep for 6 sec")
time.sleep(6)
print("done sleeping 6 secs")
with concurrent.futures.ThreadPoolExecutor() as executor:
start = time.perf_counter()
print(do_it())
executor.submit(some_func)
finish = time.perf_counter()
print(f"total time {finish-start}")
这并没有给出你想要的确切输出(两个打印语句交错),但这无关紧要,结果是一样的,t2 在 t1 完成后立即启动。