我正在將多執行緒應用于 python 腳本以提高其性能。我不明白為什么執行時間沒有改善。
這是我的實作的代碼片段:
from queue import Queue
from threading import Thread
from datetime import datetime
import time
class WP_TITLE_DOWNLOADER(Thread):
def __init__(self, queue,name):
Thread.__init__(self)
self.queue = queue
self.name = name
def download_link(self,linkss):
####some test function
###later some processing will be done on this list.
#####this will be processed on CPU.
for idx,link in enumerate(linkss):
##time.sleep(0.01)
test.append(idx)
for idx,i in enumerate(testv):
i=i.append(2)
##
def run(self):
while True:
# Get the work from the queue
linkss = self.queue.get()
try:
self.download_link(linkss)
finally:
self.queue.task_done()
######with threading
testv=[[i for i in range(5000)] for j in range(20)]
links_list=[[i for i in range(100000)] for j in range(20)]
test=[]
start_time =time.time()
queue = Queue()
thread_count=8
for x in range(thread_count):
worker = WP_TITLE_DOWNLOADER(queue,str(x))
# Setting daemon to True will let the main thread exit even though the workers are blocking
worker.daemon = True
worker.start()
##FILL UP Queue for threads
for links in links_list:
queue.put(links)
##print("queing time={}".format(time.time()-start_time))
#print(test)
#wait for all to end
j_time =time.time()
queue.join()
t_time = time.time()-start_time
print("With threading time={}".format(t_time))
#############without threading,
###following function is same as the one in threading.
test=[]
def download_link(links1):
for idx,link in enumerate(links1):
##time.sleep(0.01)
test.append(idx)
for idx,i in enumerate(testv):
i=i.append(2)
start_time =time.time()
for links in links_list:
download_link(links)
t_time = time.time()-start_time
print("without threading time={}".format(t_time))
有執行緒時間=0.564049482345581 沒有執行緒時間=0.13332700729370117
注意:當我取消注釋time.sleep時,執行緒時間低于沒有執行緒時間。我的測驗用例是我有一個串列的串列,每個串列有10000多個元素,使用多執行緒的想法是可以同時處理多個串列,而不是處理單個串列項,從而減少整體時間. 但結果并不如預期。
uj5u.com熱心網友回復:
Python 有一個名為“GIL(全域解釋器鎖)”的概念。此鎖確保在運行時只有一個執行緒查看。因此,即使您生成多個執行緒來處理多個串列,一次也只有一個執行緒在處理。您可以嘗試多處理以進行并行執行。
uj5u.com熱心網友回復:
由于 GIL(全域解釋器鎖),Python 中的執行緒很尷尬。執行緒必須競爭才能讓主解釋器能夠計算。python中的執行緒只有在執行緒內的代碼不需要全域解釋器時才有用,即。在將計算卸載到硬體加速器時、進行 I/O 系結計算或呼叫非 python 庫時。要在 python 中實作真正的并發,請改用多處理。這有點麻煩,因為您必須專門共享您的變數或復制它們并經常序列化您的通信。
uj5u.com熱心網友回復:
作為一般規則(總會有例外),多執行緒最適合 IO-bound 處理(這包括網路)。多處理非常適合 CPU 密集型活動。
因此,您的測驗存在缺陷。
您的意圖顯然是進行某種網路爬取,但這在您的測驗代碼中沒有發生,這意味著您的測驗是 CPU 密集型的,因此不適合多執行緒。然而,一旦您添加了網路代碼,您可能會發現如果您使用了合適的技術,情況會有所改善。
看看 concurrent.futures 中的 ThreadPoolExecutor。您可能會發現這特別有用,因為您可以通過簡單地將 ThreadPoolExecutor 替換為 ProcessPoolExecutor 來切換到多處理,這將使您的實驗更容易量化
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/475213.html
標籤:Python 多线程 python-多线程
