關(guān)于python線程池的四種實(shí)現(xiàn)方式
python 線程池的四種實(shí)現(xiàn)方式
線程簡(jiǎn)述
一個(gè)程序運(yùn)行起來后,一定有一個(gè)執(zhí)行代碼的東西,這個(gè)東西就是線程;
一般計(jì)算(CPU)密集型任務(wù)適合多進(jìn)程,IO密集型任務(wù)適合多線程;
一個(gè)進(jìn)程可擁有多個(gè)并行的(concurrent)線程,當(dāng)中每一個(gè)線程,共享當(dāng)前進(jìn)程的資源
以下是對(duì)發(fā)現(xiàn)的幾種多線程進(jìn)行的匯總整理,均已測(cè)試運(yùn)行 多線程實(shí)現(xiàn)的四種方式分別是:
multiprocessing下面有兩種:
from multiprocessing.dummy import Pool as ThreadPool # 線程池 from multiprocessing.pool import ThreadPool # 線程池,用法無區(qū)別,唯一區(qū)別這個(gè)是線程池
另外兩種:
from concurrent.futures import ThreadPoolExecutor # python原生線程池,這個(gè)更主流 import threadpool # 線程池,需要 pip install threadpool,很早之前的
方式1 multiprocessing.dummy Pool()
- 非阻塞方法
multiprocessing.dummy.Pool.apply_async() 和 multiprocessing.dummy.Pool.imap()
線程并發(fā)執(zhí)行
- 阻塞方法
multiprocessing.dummy.Pool.apply()和 multiprocessing.dummy.Pool.map()
線程順序執(zhí)行
from multiprocessing.dummy import Pool as Pool
import time
def func(msg):
print('msg:', msg)
time.sleep(2)
print('end:')
pool = Pool(processes=3)
for i in range(1, 5):
msg = 'hello %d' % (i)
pool.apply_async(func, (msg,)) # 非阻塞,子線程有返回值
# pool.apply(func,(msg,)) # 阻塞,apply()源自內(nèi)建函數(shù),用于間接的調(diào)用函數(shù),并且按位置把元祖或字典作為參數(shù)傳入。子線程無返回值
# pool.imap(func,[msg,]) # 非阻塞, 注意與apply傳的參數(shù)的區(qū)別 無返回值
# pool.map(func, [msg, ]) # 阻塞 子線程無返回值
print('Mark~~~~~~~~~~~~~~~')
pool.close()
pool.join() # 調(diào)用join之前,先調(diào)用close函數(shù),否則會(huì)出錯(cuò)。執(zhí)行完close后不會(huì)有新的進(jìn)程加入到pool,join函數(shù)等待所有子進(jìn)程結(jié)束
print('sub-process done')
運(yùn)行結(jié)果:

方式2:multiprocessing.pool ThreadPool Threading()
from multiprocessing.pool import ThreadPool # 線程池,用法無區(qū)別,唯一區(qū)別這個(gè)是線程池
from multiprocessing.dummy import Pool as ThreadPool # 線程池
import os
import time
print("hi outside of main()")
def hello(x):
print("inside hello()")
print("Proccess id: %s" %(os.getpid()))
time.sleep(3)
return x*x
if __name__ == "__main__":
p = ThreadPool(5)
pool_output = p.map(hello, range(3))
print(pool_output)
運(yùn)行結(jié)果:

方式3:主流ThreadPoolExecutor
from concurrent.futures import ThreadPoolExecutor
import threading
import time
# 定義一個(gè)準(zhǔn)備作為線程任務(wù)的函數(shù)
def action(max):
my_sum = 0
for i in range(max):
print(threading.current_thread().name + ' ' + str(i))
my_sum += i
return my_sum
# 創(chuàng)建一個(gè)包含2條線程的線程池
pool = ThreadPoolExecutor(max_workers=2)
# 向線程池提交一個(gè)task, 20會(huì)作為action()函數(shù)的參數(shù)
future1 = pool.submit(action, 20)
# 向線程池再提交一個(gè)task, 30會(huì)作為action()函數(shù)的參數(shù)
future2 = pool.submit(action, 30)
# 判斷future1代表的任務(wù)是否結(jié)束
print(future1.done())
time.sleep(3)
# 判斷future2代表的任務(wù)是否結(jié)束
print(future2.done())
# 查看future1代表的任務(wù)返回的結(jié)果
print(future1.result())
# 查看future2代表的任務(wù)返回的結(jié)果
print(future2.result())
# 關(guān)閉線程池
pool.shutdown()
運(yùn)行結(jié)果:

方式4:threadpool
需要 pip install threadpool
import threadpool
def hello(m, n, o):
""""""
print("m = %s, n = %s, o = %s" % (m, n, o))
if __name__ == '__main__':
# 方法1
# lst_vars_1 = ['1', '2', '3']
# lst_vars_2 = ['4', '5', '6']
# func_var = [(lst_vars_1, None), (lst_vars_2, None)]
# 方法2
dict_vars_1 = {'m': '1', 'n': '2', 'o': '3'}
dict_vars_2 = {'m': '4', 'n': '5', 'o': '6'}
func_var = [(None, dict_vars_1), (None, dict_vars_2)]
# 定義了一個(gè)線程池,表示最多可以創(chuàng)建poolsize這么多線程
pool = threadpool.ThreadPool(2)
# 調(diào)用makeRequests創(chuàng)建了要開啟多線程的函數(shù),以及函數(shù)相關(guān)參數(shù)和回調(diào)函數(shù),其中回調(diào)函數(shù)可以不寫
requests = threadpool.makeRequests(hello, func_var)
[pool.putRequest(req) for req in requests] # 將所有要運(yùn)行多線程的請(qǐng)求扔進(jìn)線程池
pool.wait() # 等待所有線程完成工作后退出
"""
[pool.putRequest(req) for req in requests]等同于
for req in requests:
pool.putRequest(req)
"""
運(yùn)行結(jié)果:

到此這篇關(guān)于關(guān)于python線程池的四種實(shí)現(xiàn)方式的文章就介紹到這了,更多相關(guān)python線程池實(shí)現(xiàn)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
python3實(shí)現(xiàn)單目標(biāo)粒子群算法
這篇文章主要為大家詳細(xì)介紹了python3實(shí)現(xiàn)單目標(biāo)粒子群算法,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-11-11
Python實(shí)現(xiàn)擴(kuò)展內(nèi)置類型的方法分析
這篇文章主要介紹了Python實(shí)現(xiàn)擴(kuò)展內(nèi)置類型的方法,結(jié)合實(shí)例形式分析了Python嵌入內(nèi)置類型擴(kuò)展及子類方式擴(kuò)展的具體實(shí)現(xiàn)技巧,需要的朋友可以參考下2017-10-10
Python實(shí)戰(zhàn)之生成有關(guān)聯(lián)單選問卷
這篇文章主要為大家分享了一個(gè)Python實(shí)戰(zhàn)小案例——生成有關(guān)聯(lián)單選問卷,并且能根據(jù)問卷總分?jǐn)?shù)生成對(duì)應(yīng)判斷文案結(jié)果,感興趣的可以了解一下2023-04-04
深入理解NumPy簡(jiǎn)明教程---數(shù)組2
這篇文章主要介紹了深入理解NumPy簡(jiǎn)明教程---數(shù)組2,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下。2016-12-12
Python中的__new__與__init__魔術(shù)方法理解筆記
這篇文章主要介紹了Python中的__new__與__init__魔術(shù)方法理解筆記,需要的朋友可以參考下2014-11-11
利用Python將彩色圖像轉(zhuǎn)為灰度圖像的兩種方法
這篇文章主要給大家介紹了關(guān)于利用Python將彩色圖像轉(zhuǎn)為灰度圖像的兩種方法,以及python 批量將圖片轉(zhuǎn)為灰度圖的方法,文中通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2021-12-12
python pip如何手動(dòng)安裝二進(jìn)制包
這篇文章主要介紹了python pip如何手動(dòng)安裝二進(jìn)制包,幫助大家更好的進(jìn)行python開發(fā),感興趣的朋友可以了解下2020-09-09

