python多執行緒

2021-10-09 17:07:20 字數 4031 閱讀 1757

每個程式執行一般會包含多個執行緒,對於python而言,它的多執行緒一般都是對於io密集型程式較為有效,因為其存在全域性直譯器鎖gil,所謂的全域性直譯器鎖,也就是只允許主迴圈中只有乙個執行緒在執行。但對於計算密集型的程式python的多執行緒就沒有什麼意義了。

全域性直譯器鎖的應用主要是為了保證資料安全,不出差錯。當多個執行緒同時對乙個資料訪問時,就會出錯。比如我們用50個執行緒向同乙個賬戶存入1塊錢時。當不使用鎖時。

import time

from threading import thread

defshow_time

(func)

:# 設定乙個修飾器

def(

*args,

**kwargs)

: start = time.time(

) func(

*args,

**kwargs)

end = time.time(

)print

(f'程式執行耗費時間'

)class

account()

:def

__init__

(self)

: self.all_money =

0 @property

defshow_money

(self)

:return self.all_money

defadd_money

(self, deposite_money)

: all_money = deposite_money + self.all_money # 此處重點 當你把此處改為self.all_money += deposite_money 是返回的資料其實還是安全的

#正是因為此處導致結果偏差,此時執行緒是不安全的

time.sleep(

0.01

) self.all_money = all_money

class

deposite_money

(thread)

:def

__init__

(self, acount, deposite_money)

:super()

.__init__(

) self.acount = acount

self.deposite_money = deposite_money

defrun(self)

: self.acount.add_money(self.deposite_money)

@show_time

defmain()

: threads =

my_acount = account(

)for i in

range(50

):a = deposite_money(my_acount,1)

a.start(

)for thread in threads:

thread.join(

)print

(f'賬戶餘額總數為'

)if __name__ ==

'__main__'

: main(

)

以下的**是使用鎖之後的

from threading import thread, lock

import time

defshow_time

(func)

:# 建立乙個修飾器顯示程式執行時間

def(

*args,

**kwargs)

: start = time.time(

) func(

*args,

**kwargs)

end = time.time(

)print

(f'程式執行耗費秒'

)

class

account()

:"""

加鎖類"""

def__init__

(self)

: self.all_money =

0 self.lock = lock(

) @property

# 修飾器 保護all_money資料,對外只顯示show_money介面

defshow_money

(self)

:return self.all_money

defadd_money

(self, deposite_money)

:# 此時的deposite_money沒有初始化,需要外部匯入

self.lock.acquire(

)# 加上執行緒鎖

try:

self.all_money += deposite_money

time.sleep(

0.05

)finally

: self.lock.release(

)# 解鎖

class

deposit_money

(thread)

:"""

建立乙個執行緒類

先是初始化__init__()

接著使用run()完成相關操作

"""def__init__

(self, acount, deposite_money)

:super()

.__init__(

) self.acount = acount # 直接匯入乙個類的例項

self.deposite_money = deposite_money

defrun(self)

: self.acount.add_money(self.deposite_money)

@show_time

defmain()

: threads =

my_count = account(

)for thread in

range(50

):# 用for迴圈建立50個執行緒

a = deposit_money(my_count,1)

a.start(

)for thread in threads:

thread.join(

)# 阻塞直到全部執行緒執行結束

print

(f'賬戶餘款總數為:'

)if __name__ ==

'__main__'

: main(

)

除了存錢的例子外,還有比如我使用乙個執行緒對乙個列表進行賦值,同一時間用另乙個執行緒對同乙個列表進行列印print()此時就會發現列印出來的可能就只是半個剛剛賦值的列表,這種情況也是衝突的。

對於函式的一些零散的應用,如map()和reduce()內建函式,map()函式有兩個引數,第乙個是函式,第二個一般是列表,返回的結果是對應值在函式中作用的結果。比如

def

multi

(x):

return x**

2map

(multi,[1

,3,4

,5])

print

(list

(map

(multi,[1

,3,4

,5])

)# 結果會是 1, 9, 16, 25

map(

int,

input()

.split())

#乙個個整數

而reduce中也是兩個引數,乙個函式,乙個常為列表,但這個函式要兩個引數,返回的結果為f(f(f(x1, x2), x3), x4)型別。

還有就是lambdas 的使用,comp = lambads x,y: x在這吐槽一下那個不知怎麼就熱起來的秋天的第一杯奶茶,對我來說秋天的第一杯奶茶是是高攀不起了,但是再等等,我應該可以吃到冬天的第一口西北風。

python多執行緒 python多執行緒

通常來說,多程序適用於計算密集型任務,多執行緒適用於io密集型任務,如網路爬蟲。關於多執行緒和多程序的區別,請參考這個 下面將使用python標準庫的multiprocessing包來嘗試多執行緒的操作,在python中呼叫多執行緒要使用multiprocessing.dummy,如果是多程序則去掉...

python多執行緒詳解 Python多執行緒詳解

前言 由於最近的工作中一直需要用到python去處理資料,而在面對大量的資料時,python多執行緒的優勢就展現出來了。因而藉此機會,盡可能詳盡地來闡述python多執行緒。但對於其更底層的實現機制,在此不做深究,僅是對於之前的一知半解做個補充,也希望初學者能夠通過這篇文章,即便是照葫蘆畫瓢,也能夠...

python程式多執行緒 PYTHON多執行緒

在單執行緒的情況下,程式是逐條指令順序執行的。同一時間只做乙個任務,完成了乙個任務再進行下乙個任務。比如有5個人吃飯,單執行緒一次只允許乙個人吃,乙個人吃完了另乙個人才能接著吃,假如每個人吃飯都需要1分鐘,5個人就需要5分鐘。多執行緒的情況下,程式就會同時進行多個任務,雖然在同一時刻也只能執行某個任...