建立一個線程池:html
import time
from concurrent.futures import ProcessPoolExecutor, as_completed def get_html(n): time.sleep(n) print('subprogram {} success'.format(n)) return n if __name__ == '__main__': executor = ProcessPoolExecutor(max_workers=2) all_task = [executor.submit(get_html, i) for i in range(3)] # 注意建立submit函數的時候,裏面的參數是單個的,並非元組形式傳入。 for futrue in as_completed(all_task): print(futrue.result()) subprogram 0 success 0 subprogram 1 success 1 subprogram 2 success 2
Future對象的理解:函數
在咱們建立submit()的時候會當即返回一個future對象,這個對象多是沒有完成的,可是會在未來某個時候完成,因此它是一個將來對象,或者叫作task的返回容器,保存task的執行狀態及執行結果。(注意future與task的區別)spa
看submit()源碼:線程
f = _base.Future()
w = _WorkItem(f, fn, args, kwargs) self._pending_work_items[self._queue_count] = w self._work_ids.put(self._queue_count) self._queue_count += 1 # Wake up queue management thread self._result_queue.put(None) self._start_queue_management_thread() return f
首先在調用submit()的時候就建立一個future, 而後將future做爲參數,和線程執行函數及參數一塊兒傳入一個_WorkItem類,因此實際上_WorkItem是線程執行的一個單元,最後再將_WorkItem類放入一線程池的隊列_work_ids中。而後計算加入的_WorkItem數量。self._queue_count,當啓動的線程數量小於線程池的max_workers時候,就會馬上啓動一個線程,該線程以_work_ids做爲參數,從裏面取出一個_WorkItem開始運行。code