python之執行緒

2021-09-29 09:04:23 字數 3620 閱讀 6424

前言

python的thread模組是比較底層的模組,python的threading模組是對thread做了一些包裝的,可以更加方便的被使用

實現執行緒的方法

使用threading模組

import threading

import time

# 注意:在寫迴圈的時候for i in range(5):要用括號把數字括起來

defsing()

:for i in

range(5

):time.sleep(1)

print

("正在唱歌"

)def

dance()

:for i in

range(5

):time.sleep(1)

print

("正在跳舞"

)def

main()

: t1 = threading.thread(target=sing)

t2 = threading.thread(target=dance)

t1.start(

) t2.start(

)if __name__ ==

'__main__'

: main(

)

說明:

可以明顯看出使用了多執行緒併發的操作,花費時間要短很多

當呼叫start()時,才會真正的建立執行緒,並且開始執行

主線程會等待所有的子執行緒結束後才結束

繼承threading.thread類重寫run方法實現多執行緒

#coding=utf-8

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(

)

說明:

多執行緒共享全域性變數

這就引出了下乙個話題執行緒安全問題

多執行緒-共享全域性變數問題

假設兩個執行緒t1和t2都要對全域性變數g_num(預設是0)進行加1運算,t1和t2都各對g_num加10次,g_num的最終的結果應該為20。

但是由於是多執行緒同時操作,有可能出現下面情況:

在g_num=0時,t1取得g_num=0。此時系統把t1排程為」sleeping」狀態,把t2轉換為」running」狀態,t2也獲得g_num=0

然後t2對得到的值進行加1並賦給g_num,使得g_num=1

然後系統又把t2排程為」sleeping」,把t1轉為」running」。執行緒t1又把它之前得到的0加1後賦值給g_num。

這樣導致雖然t1和t2都對g_num加1,但結果仍然是g_num=1

結論:

如果多個執行緒同時對同乙個全域性變數操作,會出現資源競爭問題,從而資料結果會不正確

該如何解決這個問題呢?

答案:互斥鎖

互斥鎖當多個執行緒幾乎同時修改某乙個共享資料的時候,需要進行同步控制

執行緒同步能夠保證多個執行緒安全訪問競爭資源,最簡單的同步機制是引入互斥鎖。

互斥鎖為資源引入乙個狀態:鎖定/非鎖定

某個執行緒要更改共享資料時,先將其鎖定,此時資源的狀態為「鎖定」,其他執行緒不能更改;直到該執行緒釋放資源,將資源的狀態變成「非鎖定」,其他的執行緒才能再次鎖定該資源。互斥鎖保證了每次只有乙個執行緒進行寫入操作,從而保證了多執行緒情況下資料的正確性。

使用方法

# 建立鎖

mutex = threading.lock(

)# 鎖定

mutex.acquire(

)# 釋放

mutex.release(

)

注意:

上鎖解鎖過程

總結鎖的好處:

死鎖儘管死鎖很少發生,但一旦發生就會造成應用的停止響應。下面看乙個死鎖的例子

#coding=utf-8

import threading

import time

class

mythread1

(threading.thread)

:def

run(self)

:# 對mutexa上鎖

mutexa.acquire(

)# mutexa上鎖後,延時1秒,等待另外那個執行緒 把mutexb上鎖

print

(self.name+

'----do1---up----'

) time.sleep(1)

# 此時會堵塞,因為這個mutexb已經被另外的執行緒搶先上鎖了

mutexb.acquire(

)print

(self.name+

'----do1---down----'

) mutexb.release(

)# 對mutexa解鎖

mutexa.release(

)class

mythread2

(threading.thread)

:def

run(self)

:# 對mutexb上鎖

mutexb.acquire(

)# mutexb上鎖後,延時1秒,等待另外那個執行緒 把mutexa上鎖

print

(self.name+

'----do2---up----'

) time.sleep(1)

# 此時會堵塞,因為這個mutexa已經被另外的執行緒搶先上鎖了

mutexa.acquire(

)print

(self.name+

'----do2---down----'

) mutexa.release(

)# 對mutexb解鎖

mutexb.release(

)mutexa = threading.lock(

)mutexb = threading.lock(

)if __name__ ==

'__main__'

: t1 = mythread1(

) t2 = mythread2(

) t1.start(

) t2.start(

)

避免死鎖的方法:

python之執行緒

程序和執行緒都是虛擬單位,只是為了我們更加方便的描述問題 3.1 方式一 from threading import thread import time def task name print f is running time.sleep 1 print f is stopping 開執行緒的 ...

Python學習 之 執行緒

from threading import thread import time import random 用於併發執行的函式 deftask num time.sleep random.randint 1,3 print num if name main 建立乙個用於存放執行緒的 list 這種...

python之執行緒入門

import threading import time class mythread threading.thread def init self,threadid,threadname,counter threading.thread.init self self.threadid thread...