欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Python線程之同步機(jī)制實(shí)際應(yīng)用場景舉例說明

 更新時間:2022年02月24日 10:04:32   作者:雷學(xué)委  
這篇文章主要給大家分享的是Python線程之同步機(jī)制實(shí)際應(yīng)用場景舉例說明,銀行轉(zhuǎn)賬小栗子供大家參考學(xué)習(xí),希望對你有一定的幫助

這次讓我們來看看一個真實(shí)場景吧:銀行轉(zhuǎn)賬

一、舉例銀行轉(zhuǎn)賬

假設(shè)現(xiàn)在有一個xuewei的賬號里面有 100W。

然后有多個任務(wù)在轉(zhuǎn)賬,轉(zhuǎn)入轉(zhuǎn)出都是跟這個xuewei賬號相關(guān)的。

而且這些任務(wù)發(fā)生是隨機(jī)的。

我們先把上面的場景寫成代碼:

xuewei_account = 100


# amount為負(fù)數(shù)即是轉(zhuǎn)出金額
def transfer(money):
? ? global xuewei_account
? ? xuewei_account += money

下面是多個線程,多線程模擬轉(zhuǎn)賬事件,我們假設(shè)有4個事件在同時發(fā)生。

import random
import threading
import datetime
import time

xuewei_account = 100


# amount為負(fù)數(shù)即是轉(zhuǎn)出金額
def transfer(money):
? ? global xuewei_account
? ? xuewei_account += money


# 創(chuàng)建4個任務(wù)給學(xué)委賬戶轉(zhuǎn)賬
for i in range(10000):
? ? threading.Thread(target=lambda: transfer(-1)).start()
? ? threading.Thread(target=lambda: transfer(1)).start()
? ? threading.Thread(target=lambda: transfer(-1)).start()
? ? threading.Thread(target=lambda: transfer(1)).start()

# 等待活躍線程只剩下主線程MainThread
time.sleep(10)
print("-" * 16)
print("活躍線程數(shù):", threading.active_count())
print("活躍線程:", threading.current_thread().name)
print("學(xué)委賬戶余額:", xuewei_account)

這里啟動了4個線程循環(huán)了10000次,也就是4萬個線程,分別于學(xué)委的賬戶進(jìn)行轉(zhuǎn)賬。

下面是運(yùn)行結(jié)果:

運(yùn)行幾次學(xué)委的賬戶還是正確的,余額還是100W。

上面的代碼線程幾萬個,但每次運(yùn)行的操作都很簡單,完成一次加法。

線程一個接一個start,非??焖倬颓袚Q下一個線程, 我們看到程序沒有出現(xiàn)問題。

下面進(jìn)行改造,這次不要就4萬線程了,我們讓轉(zhuǎn)賬這個任務(wù)耗時更多,每啟動一個線程進(jìn)行模擬10萬次轉(zhuǎn)賬。

import random
import threading
import datetime
import time

xuewei_account = 100


# amount為負(fù)數(shù)即是轉(zhuǎn)出金額
def transfer(money):
? ? global xuewei_account
? ? for x in range(100000):
? ? ? ? xuewei_account += money

 創(chuàng)建4個任務(wù)給重復(fù)學(xué)委賬戶轉(zhuǎn)賬:

for i in range(10):
? ? threading.Thread(target=lambda: transfer(-1)).start()
? ? threading.Thread(target=lambda: transfer(1)).start()
? ? threading.Thread(target=lambda: transfer(-1)).start()
? ? threading.Thread(target=lambda: transfer(1)).start()

time.sleep(10)
print("-" * 16)
print("活躍線程數(shù):", threading.active_count())
print("活躍線程:", threading.current_thread().name)
print("學(xué)委賬戶余額:", xuewei_account)

這里運(yùn)行的結(jié)果就比較出乎意料了:

多線程編程復(fù)雜的地方就在這里了, 有時候明明平平無奇的代碼,改造成多線程,就很容易出bug!

當(dāng)然上面的代碼并不是平平無奇,相比第一段代碼,上面的轉(zhuǎn)賬函數(shù)做的事件更多,更耗時。

二、問題解決

我們加上鎖。

代碼如下:

import random
import threading
import datetime
import time

xuewei_account = 100

lock = threading.Lock()
# amount為負(fù)數(shù)即是轉(zhuǎn)出金額
def transfer(money):
? ? lock.acquire()
? ? global xuewei_account
? ? for x in range(100000):
? ? ? ? xuewei_account += money
? ? lock.release()


# 創(chuàng)建4個任務(wù)給重復(fù)學(xué)委賬戶轉(zhuǎn)賬
for i in range(10):
? ? threading.Thread(target=lambda: transfer(-1)).start()
? ? threading.Thread(target=lambda: transfer(1)).start()
? ? threading.Thread(target=lambda: transfer(-1)).start()
? ? threading.Thread(target=lambda: transfer(1)).start()

time.sleep(10)
print("-" * 16)
print("活躍線程數(shù):", threading.active_count())
print("活躍線程:", threading.current_thread().name)
print("學(xué)委賬戶余額:", xuewei_account)

運(yùn)行結(jié)果如下:

上面的代碼不管怎么運(yùn)行,運(yùn)行多少次最后學(xué)委的賬戶都是100.(PS:學(xué)委不會聯(lián)系讀者轉(zhuǎn)賬的,這個特別注意)。

不管多少個線程,每次轉(zhuǎn)賬函數(shù)內(nèi)部轉(zhuǎn)賬的代碼(從global到 += money這一段代碼)只會被一個線程調(diào)用。

三、總結(jié)

展示了同步機(jī)制解決一些編程問題的思路。讀者可以多多借鑒,思考鎖的應(yīng)用。

為什么在對amount重度操作(本文第二段代碼)的時候,計算就出錯了!

這里amount相當(dāng)于多線程都在操作的變量,也就是共享變量,多線程編程要特別注意這類變量,避免出現(xiàn)對共享變量的操作,有些程序在并發(fā)規(guī)模很小的時候一點(diǎn)問題也沒有。

并發(fā)編程是高度利用CPU計算能力的編程方式,并發(fā)程序也就是在并行執(zhí)行同類任務(wù)的程序。這個可以跟單線程應(yīng)用比較。

到此這篇關(guān)于Python線程之同步機(jī)制實(shí)際應(yīng)用場景舉例說明的文章就介紹到這了,更多相關(guān)Python線程同步機(jī)制內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 基于Keras的擴(kuò)展性使用

    基于Keras的擴(kuò)展性使用

    這篇文章主要介紹了Keras的擴(kuò)展性使用操作,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-05-05
  • python實(shí)現(xiàn)將兩個文件夾合并至另一個文件夾(制作數(shù)據(jù)集)

    python實(shí)現(xiàn)將兩個文件夾合并至另一個文件夾(制作數(shù)據(jù)集)

    這篇文章主要介紹了python實(shí)現(xiàn)將兩個文件夾合并至另一個文件夾(制作數(shù)據(jù)集),具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-04-04
  • Python+Turtle繪制可愛的可達(dá)鴨

    Python+Turtle繪制可愛的可達(dá)鴨

    一年一度的六一兒童節(jié)又來了,祝大朋友小朋友節(jié)日快樂!本文主要介紹如何運(yùn)用Python中的turtle庫控制函數(shù)繪制可達(dá)鴨,希望你會喜歡
    2022-05-05
  • 最新評論