线程池使用
1. 基本用法
1 2 3 4 5 6 7 8 9 10 11 12 13
| import concurrent.futures
def func(): print("thread start!")
thread_num = 3 with concurrent.futures.ThreadPoolExecutor(max_workers=thread_num) as pool: pool.submit(func)
|
2. 获取线程工作状态
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| import concurrent.futures import time
def func(): print("thread start!") time.sleep(5)
thread_num = 3 with concurrent.futures.ThreadPoolExecutor(max_workers=thread_num) as pool: future = pool.submit(func) if future.done(): print("thread done!") else: print("thread not done!")
|
3. 获取线程返回值
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| import concurrent.futures import time
def func(): print("thread start!") time.sleep(5) return "func return!"
thread_num = 3 with concurrent.futures.ThreadPoolExecutor(max_workers=thread_num) as pool: future = pool.submit(func) print(future.result()) ''' thread start! func return! '''
|
4. 向线程传递参数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
| import concurrent.futures import time
def func(thread_idx, sleep_secs): print("thread_idx = %d" % thread_idx) time.sleep(sleep_secs) return "thread_%d sleep_secs:%d return!" % (thread_idx, sleep_secs)
thread_num = 3 with concurrent.futures.ThreadPoolExecutor(max_workers=thread_num) as pool: future1 = pool.submit(func, 1, 4) params = (2, 3) future2 = pool.submit(func, *params) params_map = { "sleep_secs" : 2, "thread_idx" : 3 } future3 = pool.submit(func, **params_map) print(future1.result())
print(future2.result()) print(future3.result()) ''' thread_idx = 1 thread_idx = 2 thread_idx = 3 thread_1 sleep_secs:4 return! thread_2 sleep_secs:3 return! thread_3 sleep_secs:2 return! '''
|
5. 无阻塞获得返回值
在第4节中会发现 ,当调用future1.result()
时,如果future1对应的线程还没有结束,那么就会阻塞在这里等待future1结束,那么即使future2先结束了,也不能提前得到主线程的处理。
接下来介绍「只要有线程执行完毕就立即获得响应」的方式。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
| import concurrent.futures import time
def func(thread_idx, sleep_secs): print("thread_idx = %d" % thread_idx) time.sleep(sleep_secs) return "func return sleep_secs = %d" % sleep_secs
thread_num = 3 future_list = [] with concurrent.futures.ThreadPoolExecutor(max_workers=thread_num) as pool: for sleep_sec in range(5): params_map = { "sleep_secs" : 5 - sleep_sec, "thread_idx" : sleep_sec } future_list.append(pool.submit(func, **params_map)) for future in concurrent.futures.as_completed(future_list): print(future.result()) ''' thread_idx = 0 thread_idx = 1 thread_idx = 2 thread_idx = 3 func return sleep_secs = 3 thread_idx = 4 func return sleep_secs = 4 func return sleep_secs = 5 func return sleep_secs = 1 func return sleep_secs = 2 '''
|
7. 异常处理
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| import concurrent.futures import time
def func(): print("thread start!") time.sleep(3) raise(Exception("manual error")) return "func return!"
thread_num = 3 with concurrent.futures.ThreadPoolExecutor(max_workers=thread_num) as pool: future = pool.submit(func) print(future.exception()) ''' thread start! manual error ''' print(future.result())
|
多线程 + 生成器获取返回值
1. 生成器Generator
当一个函数中出现yield
时,它就会变成一个Generator
,一般用for循环遍历,也可以手动调用它的.next()
函数。
Generator
的特性是:遇到yield,则返回yield表达式中的内容,同时暂停运行,直到下一次调用.next()
时再从yield的下一条语句继续执行。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| def counter(target): for i in range(target): yield i counter_generator = counter(10) for item in counter_generator: print(item) ''' 0 1 2 3 4 5 6 7 8 9 '''
|
2. 使用Generator获取线程返回值
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
| import concurrent.futures import time
def func(num, sleep_secs): time.sleep(sleep_secs) return num * 2 def run_async(): thread_num = 3 with concurrent.futures.ThreadPoolExecutor(max_workers=thread_num) as pool: future_list = [] for i in range(10): params_map = { "sleep_secs" : 1, "num" : i } future_list.append(pool.submit(func, **params_map)) for future in concurrent.futures.as_completed(future_list): yield future.result() results = run_async() for r in results: print(r) ''' 2 4 0 10 8 6 12 14 16 18 '''
|