python的thread模組是⽐較底層的模組,python的threading
模組是對thread做了⼀些包裝的,可以更加⽅便的被使⽤
1. 執行緒執⾏**的封裝
通過上⼀⼩節,能夠看出,通過使⽤threading模組能完成多工的程式開
發,為了讓每個執行緒的封裝性更完美,所以使⽤threading模組時,往往會定
義⼀個新的⼦類class,只要繼承 threading.thread 就可以了,然後重
寫 run ⽅法
import threading
import time
class mythread(threading.thread):
def run(self):
for i in range(3):
time.sleep(1)
msg = "i'm "+self.name+' @ '+str(i) #name屬性中儲存的是當前執行緒的名字
print(msg)
if __name__ == '__main__':
t = mythread()
t.start()
import threading
import time
class mythread(threading.thread):
def run(self):
for i in range(3):
time.sleep(1)
msg = "i'm "+self.name+' @ '+str(i)
print(msg+"\n")
def test():
for i in range(5):
t = mythread()
t.start()
if __name__ == '__main__':
test()
說明從**和執⾏結果我們可以看出,多執行緒程式的執⾏順序是不確定的。當執
⾏到sleep語句時,執行緒將被阻塞(blocked),到sleep結束後,執行緒進⼊就
緒(runnable)狀態,等待排程。⽽執行緒排程將⾃⾏選擇⼀個執行緒執⾏。上
⾯的**中只能保證每個執行緒都運⾏完整個run函式,但是執行緒的啟動順序、
run函式中每次迴圈的執⾏順序都不能確定。
總結:
在⼀個程序內的所有執行緒共享全域性變數,能夠在不適⽤其他⽅式的前提下完成多執行緒之間的資料共享(這點要⽐多程序要好)
缺點就是,執行緒是對全域性變數隨意遂改可能造成多執行緒之間對全域性變數
的混亂(即執行緒⾮安全)
from threading import thread
import time
g_num = 0
def test1():
global g_num
for i in range(1000000):
g_num += 1
print("---test1---g_num=%d"%g_num)
def test2():
global g_num
for i in range(1000000):
g_num += 1
print("---test2---g_num=%d"%g_num)
p1 = thread(target=test1)
p1.start()
# time.sleep(3) #取消遮蔽之後 再次運⾏程式,結果會不⼀樣,,,為啥呢?
當多個執行緒⼏乎同時修改某⼀個共享資料的時候,需要進⾏同步控制
執行緒同步能夠保證多個執行緒安全訪問競爭資源,最簡單的同步機制是引⼊互
斥鎖。互斥鎖為資源引⼊⼀個狀態:鎖定/⾮鎖定。
某個執行緒要更改共享資料時,先將其鎖定,此時資源的狀態為「鎖定」,其他
執行緒不能更改;直到該執行緒釋放資源,將資源的狀態變成「⾮鎖定」,其他的
執行緒才能再次鎖定該資源。互斥鎖保證了每次只有⼀個執行緒進⾏寫⼊操作,
從⽽保證了多執行緒情況下資料的正確性。
from threading import thread,lock
import time
g_num = 0
def test1():
global g_num
for i in range(1000000):
lock1.acquire() #上鎖
g_num += 1
lock1.release() #開鎖
print("---test1---g_num=%d"%g_num)
def test2():
global g_num
for i in range(1000000):
lock1.acquire() #上鎖
g_num += 1
lock1.release() #開鎖
print("---test2---g_num=%d"%g_num)
if __name__ == '__main__':
lock1 = lock() #建立⼀個互斥鎖,這個所預設是未上鎖的狀態
t1 = thread(target=test1)
t1.start()
t2 = thread(target=test2)
t2.start()
print("----g_num=%d--------"%g_num)
當⼀個執行緒調⽤鎖的acquire()⽅法獲得鎖時,鎖就進⼊「locked」狀態。
每次只有⼀個執行緒可以獲得鎖。如果此時另⼀個執行緒試圖獲得這個鎖,該線
程就會變為「blocked」狀態,稱為「阻塞」,直到擁有鎖的執行緒調⽤鎖的
release()⽅法釋放鎖之後,鎖進⼊「unlocked」狀態。
執行緒排程程式從處於同步阻塞狀態的執行緒中選擇⼀個來獲得鎖,並使得該線
程進⼊運⾏(running)狀態。
鎖的好處:
確保了某段關鍵**只能由⼀個執行緒從頭到尾完整地執⾏
鎖的壞處:
阻⽌了多執行緒併發執⾏,包含鎖的某段**實際上只能以單執行緒模式執
⾏,效率就⼤⼤地下降了
由於可以存在多個鎖,不同的執行緒持有不同的鎖,並試圖獲取對⽅持有
的鎖時,可能會造成死鎖
threading多執行緒
什麼是執行緒?執行緒是作業系統能夠進行運算排程的最小單位。它被包含在程序之中,是程序中的實際運作單位。一條執行緒指的是程序中乙個單一順序的控制流,乙個程序中可以併發多個執行緒,每條執行緒並行執行不同的任務。乙個程序中可以包含多個執行緒。1 import threading 2import time ...
python 多執行緒 Threading
簡單的多執行緒 python 2.7 coding utf 8 import threading defrun thread while true cmd input input you choice print cmd if cmd 0 print thread exit break else p...
Python 多執行緒 threading
import threading defthread job print this is a thread of s threading.current thread defmain thread threading.thread target thread job,定義執行緒 thread.sta...