python線程池的使用


1.創建線程池ThreadPoolExecutor,提交任務submit(),查詢狀態done(),獲取結果result()

from concurrent.futures import ThreadPoolExecutor
import time


def get_html(times):
    time.sleep(times)
    print('{}, finished'.format(times))
    return times


executor = ThreadPoolExecutor(max_workers=2);   #創建線程池,傳入max_workers參數來設置線程池中最多能同時運行的線程數目

task1 = executor.submit(get_html, 3)      # 提交任務
task2 = executor.submit(get_html, 2)
print(task1.done())     # 查詢任務狀態,完成返回True,否則返回False
print(task2.done())
time.sleep(4)
print(task1.done())
print(task2.done())
print(task1.result())      # 獲取任務的返回值,注意:這個方法會阻塞主線程,等待這個任務執行完得到結果
print(task2.result())


if __name__ == '__main__':
    pass

2.取消任務cancel()

from concurrent.futures import ThreadPoolExecutor
import time


def get_html(times):
    time.sleep(times)
    print('{}, finished'.format(times))
    return times


executor = ThreadPoolExecutor(max_workers=1);   #創建線程池

task1 = executor.submit(get_html, 3)      # 提交任務
task2 = executor.submit(get_html, 2)
task1.cancel()
task2.cancel()
"""
    使用cancel()方法可以取消提交的任務,如果任務已經在線程池中運行了,就取消不了
    上面的例子,線程池大小為1,添加兩個線程后,第一個線程已經在線程池運行,取消不了,第二個線程還在等待,所以可以取消
"""

if __name__ == '__main__':
    pass

執行結果

3, finished

3.as_completed()

from concurrent.futures import ThreadPoolExecutor, as_completed
import time


def get_html(times):
    time.sleep(times)
    print('{}, finished'.format(times))
    return times


executor = ThreadPoolExecutor(max_workers=3);   #創建線程池

task1 = executor.submit(get_html, 5)      # 提交任務
task2 = executor.submit(get_html, 2)


for future in as_completed([task1, task2]):
    print(future.result())
"""
    as_completed()方法是一個生成器,在沒有任務完成的時候,會阻塞,在有某個任務完成的時候,會yield這個任務,就能執行for循環下面的語句,然后繼續阻塞住,循環到所有的任務結束。
    從結果也可以看出,先完成的任務會先通知主線程。
"""

if __name__ == '__main__':
    pass

執行結果:

2, finished
2
5, finished
5
  • 循環等待任務執行完過程中如果某個線程拋出異常,則循環停止執行

4. map()

from concurrent.futures import ThreadPoolExecutor, as_completed
import time


def get_html(times):
    time.sleep(times)
    return times


executor = ThreadPoolExecutor(max_workers=3);   #創建線程池

time_list = [5, 2, 4]

for data in executor.map(get_html, time_list):
    print(data)

"""
    使用map方法,無需提前使用submit方法,map方法與python標准庫中的map含義相同,都是將序列中的每個元素都執行同一個函數。這里是執行submit函數
    上面的代碼就是對time_list的每個元素都執行get_html函數,並分配給線程池。
    可以看到執行結果與上面的as_completed方法的結果不同,輸出順序和time_list列表的順序對應,就算2s的任務先執行完成,也會先打印出5s的任務先完成,再打印2s的任務完成。
"""

if __name__ == '__main__':
    pass

執行結果:

5
2
4

5. wait()

from concurrent.futures import ThreadPoolExecutor, as_completed, wait, ALL_COMPLETED
import time


def get_html(times):
    time.sleep(times)
    print("{} task finish".format(times))
    return times


executor = ThreadPoolExecutor(max_workers=3);   #創建線程池

task1 = executor.submit(get_html, 5)
task2 = executor.submit(get_html, 2)

wait([task1, task2], return_when=ALL_COMPLETED)
print("end")


"""
   wait方法接收3個參數,等待的任務序列、超時時間以及等待條件。等待條件return_when默認為ALL_COMPLETED,表明要等待所有的任務都結束。
   可以看到運行結果中,確實是所有任務都完成了,主線程才打印出end。
   等待條件還可以設置為FIRST_COMPLETED,表示第一個任務完成就停止等待。

"""

if __name__ == '__main__':
    pass

執行結果:

2 task finish
5 task finish
end

 6.shutdown()

from concurrent.futures import ThreadPoolExecutor, as_completed, wait, ALL_COMPLETED
import time


def get_html(times):
    time.sleep(times)
    print("{} task finish".format(times))
    return times


executor = ThreadPoolExecutor(max_workers=3);   #創建線程池

task1 = executor.submit(get_html, 3)
task2 = executor.submit(get_html, 2)

for f in as_completed([task1, task2]):
    print(f.result())
executor.shutdown()


"""
   在用完一個線程池后,應該調用線程池的shutdown()方法,該方法將啟動線程池的關閉序列。
   調用shutdown()方法后的線程池不再接受新任務,但會將以前所有已提交的任務執行完成。當線程池中的所有任務都執行完后,該線程池中的所有線程都會死亡

"""

if __name__ == '__main__':
    pass

執行結果:

2 task finish
2
3 task finish
3

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM