多執行緒是什麼呢?
多執行緒是加速程式計算的有效方式,python的多執行緒模組threading上手快速簡單
新增執行緒
import threading
defadding_thread()
:print
("this is new thread %s"
%threading.current_thread())
defthread_work()
: thread=threading.thread(target=adding_thread)
#定義執行緒(target 目標,要使執行緒做乙個工作)
thread.start(
)#讓執行緒開始工作
print
(threading.active_count())
#獲得已啟用的執行緒數
print
(threading.
enumerate()
)#檢視所有執行緒資訊
print
(threading.current_thread())
#檢視現在正在執行的執行緒
if __name__ ==
"__main__"
: thread_work(
)
結果如下:
/users/lenovo/多執行緒/新增執行緒.py
this is new thread 1, started 13684
)>1[
<_mainthread(mainthread, started 11408
)>
]<_mainthread(mainthread, started 11408
)>
process finished with exit code 0
join功能
首先 join有什麼用? 他是用來確定執行緒何時結束的 ,如果有呼叫它的,主線程會一直等待,直到指定的執行緒加入它。
來看一下例子:
不加join時且把t1執行緒的執行耗時加長:
import threading
import time
deft1_work()
:print
("t1 start\n"
)for i in
range(10
):time.sleep(
0.1)
#任務間隔0.1秒
print
("t1 over\n"
)add_thread=threading.thread(target=t1_work,name=
"t1"
)add_thread.start(
)print
("all over\n"
)
結果
/users/lenovo/多執行緒/join功能.py
t1 start
all over
t1 over
但我們的預想結果為:
所以我們可以用join()把執行緒加入到主線程中
/users/lenovo/多執行緒/join功能.py
t1 start
t1 over
all over
執行緒任務還未完成時便輸出all over,若想要執行緒任務完成再輸出,則可啟動執行緒後呼叫join()
import threading
import time
deft1_work()
:print
("t1 start\n"
)for i in
range(10
):time.sleep(
0.1)
#任務間隔0.1秒
print
("t1 over\n"
)add_thread=threading.thread(target=t1_work,name=
"t1"
)add_thread.start(
)add_thread.join(
)#在這裡我們呼叫了join(),這裡的結果便為我們預期的
print
("all over\n"
)
儲存多執行緒結果queue
多執行緒函式中定義乙個queue,用來儲存返回值,代替return,定義乙個多執行緒列表,初始化乙個多維資料列表,用來處理:
import threading
from queue import queue
defjob
(l,q)
:#定義乙個被多執行緒呼叫的函式功能例表裡的每乙個數乘以平方
for i in
range
(len
(l))
: l[i]
=l[i]**2
q.put(l)
#加入佇列裡
defmultithreading()
: q=queue(
) thread=
data=[[
1,2,
3],[
2,3,
4],[
4,4,
4],[
5,5,
5]]for i in
range(4
):#功能開始四個多執行緒
add_threading=threading.thread(target=job,args=
(data[i]
,q))
add_threading.start(
)for li in thread:
#加入到主線程中
li.join(
) results=
for i in
range(4
):))
print
(results)
if __name__==
"__main__"
: multithreading(
)
結果:
[[1
,4,9
],[4
,9,16
],[16
,16,16
],[25
,25,25
]]
關於gif
python 的多執行緒 threading 有時候並不是特別理想. 最主要的原因是就是, python 的設計上, 有乙個必要的環節, 就是global interpreter lock (gil). 這個東西讓 python 還是一次性只能處理乙個東西.
儘管python完全支援多執行緒程式設計, 但是直譯器的c語言實現部分在完全並行執行時並不是執行緒安全的。
實際上,直譯器被乙個全域性直譯器鎖保護著,它確保任何時候都只有乙個python執行緒執行。
gil最大的問題就是python的多執行緒程式並不能利用多核cpu的優勢
(比如乙個使用了多個執行緒的計算密集型程式只會在乙個單cpu上面執行)。
在討論普通的gil之前,有一點要強調的是gil只會影響到那些嚴重依賴cpu的程式(比如計算型的)。
如果你的程式大部分只會涉及到i/o,比如網路互動,那麼使用多執行緒就很合適,
因為它們大部分時間都在等待。實際上,你完全可以放心的建立幾千個python執行緒, 現代作業系統執行這麼多執行緒沒有任何壓力,沒啥可擔心的。
執行緒鎖lock
執行lock.acquire()將共享記憶體上鎖, 確保當前執行緒執行時,記憶體不會被其他執行緒訪問,執行運算完畢後,使用lock.release()將鎖開啟, 保證其他的執行緒可以使用該共享記憶體。(少使用)
import threading
#不使用lock
defjob1()
:global a,lock
lock.acquire(
)for i in
range(10
):a=a+
1print
("job1"
,a) lock.release(
)def
job2()
:global a
lock.acquire(
)for i in
range(10
):a=a+
10print
("job2"
,a) lock.release(
)def
adding_work()
: adding_thread1=threading.thread(target=job1)
adding_thread2=threading.thread(target=job2)
adding_thread1.start(
) adding_thread2.start(
) adding_thread2.join(
) adding_thread1.join(
)if __name__==
"__main__"
: lock=threading.lock(
)#主函式中定義乙個lock
a=0 adding_work(
)
參考:莫煩python 學習日記之多執行緒
要學習執行緒,首先要理解三個概念。什麼是程式,什麼是程序,什麼是執行緒。程式,是指令的集合。程序是正在執行的程式,是靜態概念。執行緒,是程序中乙個 單一的連續控制流程 也稱為輕量級程序。執行緒有一下幾個點 1.乙個程序可以擁有多個執行緒 2.乙個程序中的執行緒個共享相同的記憶體單元,即擁有相同的變兩...
python之多執行緒(學習)
執行緒分為 核心執行緒 由作業系統核心建立和撤銷 使用者執行緒 不需要核心支援而在使用者程式中實現的執行緒python3 執行緒中常用的兩個模組 thread和threading 推薦使用 python中使用執行緒有兩種方式 函式或者用類來包裝執行緒物件函式式 呼叫模組 import thread ...
莫煩pytorch學習筆記
此處x,y為資料集的tensor torch dataset data.tensordataset data tensor x,target tensor y loader data.dataloader dataset torch dataset,batch size batch size,shu...