莫煩python之python多執行緒
地址:https://morvanzhou.github.io/tutorials/python-basic/threading/1-why/
多執行緒
一、新增執行緒
import threading
import time
def thread_job():
print("T1 start\n")
for i in range(10):
time.sleep(0.1) # 任務間隔0.1s
print("T1 finish\n")
def main():
added_thread = threading.Thread(target=thread_job, name='T1')
added_thread.start()
print("all done\n")
if __name__ == '__main__': # 如果模組是被直接執行的,則程式碼塊被執行,如果模組是被匯入的,則程式碼塊不被執行。
main()
執行結果: T1 start
all done
T1 finish
二、join功能
在上面例子基礎上修改
def main():
added_thread = threading.Thread(target=thread_job, name='T1')
added_thread.start()
added_thread.join() #等待該執行緒執行完才執行後面語句
print("all done\n")
三、queue:執行緒無法返回值,把結果放到一個佇列,主執行緒中取到
def job(l,q):
for i in range(len(l)):
l[i] = l[i]**2
q.put(l) #結果放到一個佇列
def multithreading():
q = Queue()
threads = []
data = [[1,2,3],[3,4,5],[4,4,4],[5,5,5]]
for i in range(4): #建立四個執行緒,每個執行緒一個小佇列
t = threading.Thread(target=job,args=(data[i],q))
t.start()
threads.append(t)
for thread in threads: #所有執行緒運算完畢繼續後面
thread.join()
results = []
for _ in range(4): #把結果放到results中列印
results.append(q.get())
print(results)
if __name__ == '__main__':
multithreading()
四、GIL(Global Interpreter Lock )不一定有效率,純運算速度沒有提升太高
測試:
import threading
from queue import Queue
import copy
import time
def job(l, q):
res = sum(l)
q.put(res)
def multithreading(l):
q = Queue()
threads = []
for i in range(4):
t = threading.Thread(target=job, args=(copy.copy(l), q), name='T%i' % i)
t.start()
threads.append(t)
[t.join() for t in threads]
total = 0
for _ in range(4):
total += q.get()
print(total)
def normal(l):
total = sum(l)
print(total)
if __name__ == '__main__':
l = list(range(1000000))
s_t = time.time()
normal(l*4)
print('normal: ',time.time()-s_t)
s_t = time.time()
multithreading(l)
print('multithreading: ', time.time()-s_t)
運算結果
1999998000000
normal: 0.29871177673339844
1999998000000
multithreading: 0.2837047576904297
使用了多執行緒但是對於純運算速度沒有提升太高,同一時刻只有一個核在運算
後面會用到多核的運算
五、執行緒鎖:為了讓A完成後在處理B
import threading
def job1():
global A
for i in range(10):
A+=1
print('job1',A)
def job2():
global A
for i in range(10):
A+=10
print('job2',A)
if __name__== '__main__':
A=0
t1=threading.Thread(target=job1)
t2=threading.Thread(target=job2)
t1.start()
t2.start()
t1.join()
t2.join()
不知道為什麼我不用lock也沒有衝突