python併發程式設計調優 python併發程式設計

2021-10-13 02:37:21 字數 3752 閱讀 8354

併發程式設計是我們程式設計中常用的優化程式效能的手段,能提高cpu的使用率。一般使用是多執行緒,多程序,協程

一、python的全域性解釋鎖gil

我們目前跑的python程式大多數都是在cpython上執行的。cpython是有乙個全域性解釋鎖,具體什麼意思,可以兩個方面理解

在同一時刻,只能執行乙個執行緒

無法將多個執行緒對映到多個cpu上執行

也就是說python多執行緒是有一定侷限性的,對於io密集型的任務,我們可以很好的利用多執行緒,對於計算密集型的任務,多執行緒就沒有意義了,只能利用多程序提高效能

二、簡單多執行緒程式設計

第一種形式:使用threading庫,直接使用thread類

fromthreading import thread

import time

def fun(n):

#dosomething

time.sleep(n)

print(n)

t1= thread(target=fun, args=(1,))

t2= thread(target=fun, args=(2,))

# 啟動執行緒

t1.start()

t2.start()

# 等待執行緒結束

t1.join()

t2.join()

第二種形式:使用threading庫,繼承thread類

fromthreading import thread

import timeclassmythread(thread):

def __init__(self, n):

self.n=n

super().__init__()

def run(self):

time.sleep(self.n)

print(self.n)

t1= mythread(1)

t2= mythread(2)

t1.start()

t2.start()

t1.join()

t2.join()

三、執行緒安全

多個執行緒在同乙個程序中執行時,是共享記憶體空間的,這就有可能引起乙個執行緒在修改乙個變數到一半的時候去休息了,回來的時候發現這個變數變了,這就會產生問題

如何保證執行緒安全,一般有下面幾個方法

使用私有變數,每個執行緒都只知道自己的變數,其他執行緒無法修改,一般通過區域性變數實現

通過拷貝資料到自己的空間,自己修改自己拷貝的資料,這樣不會影響其他執行緒,一般通過thread.local實現

控制共享變數的訪問方式,同一時刻只能有乙個執行緒修改,一般通過加鎖實現

還有一些其他方法保證執行緒安全,不同的場景,保證執行緒安全的方法也不同,需要合理採用。下面用**說明一下

首先,我們不加鎖,有兩個執行緒共同操作乙個共享變數

# 沒有使用鎖的情況fromthreading import thread

n= 0def add():globalnfor i in range(1000000):

n+= 1def sub():globalnfor i in range(1000000):

n-= 1t1= thread(target=add)

t2= thread(target=sub)

t1.start()

t2.start()

t1.join()

t2.join()

print(n)

輸出的結果,發現不是我們想象中的0,這就是因為兩個執行緒執行期間,乙個執行緒把 對n的操作執行到一半時候,去休息了,回來繼續執行剩下一半的過程中,另乙個執行緒修改了n,這樣就造成了執行緒不安全的問題,最後的結果不一致。

加鎖後的**

fromthreading import thread, lock

n= 0

lock =lock()

def add(lock):globalnfor i in range(1000000):lock.acquire()

n+= 1

lock.release()

def sub(lock):globalnfor i in range(1000000):lock.acquire()

n-= 1

lock.release()

t1= thread(target=add, args=(lock,))

t2= thread(target=sub, args=(lock,))

t1.start()

t2.start()

t1.join()

t2.join()

print(n)

這次輸出的結果都是0了,我們在整個修改共享變數的過程中,加了鎖,在鎖未釋放的時候,其他執行緒是執行不了的

四、執行緒間通訊

執行緒間通訊最常用的是佇列,python提供了乙個執行緒安全的佇列,from queue import queue,在多個執行緒之間操作佇列裡的元素都是安全的

還有更加複雜的執行緒通訊機制,比如條件變數,訊號量等,python也提供了相應的模組

五、執行緒池

有時候,我們有很多條資料,我們希望同一時刻總共有5個執行緒來處理這一批資料,乙個執行緒結束後,再啟動另乙個執行緒,總數不能超過5個,這時候執行緒池就可以很好的解決我們的問題了

fromconcurrent.futures.thread import threadpoolexecutorfromconcurrent.futures import wait

import time

pools= threadpoolexecutor(5)

data= list(range(20))

res=

def fun(n):

time.sleep(2)

print(n)returnnfor n indata:

# 等待所有執行緒執行完畢

wait(res)

執行緒池還給我們提供了更多的功能,我們可以獲取執行緒返回的結果

fromconcurrent.futures.thread import threadpoolexecutorfromconcurrent.futures import as_completed

import time

pools= threadpoolexecutor(5)

data= list(range(20))

res=

def fun(n):

time.sleep(2)returnnfor n indata:

# 獲取執行緒結束後的結果for r inas_completed(res):

print(r.result())

六、多程序程式設計

關於python多程序,在大多數業務開發中,用的比較少,我只給出乙個簡單的例子(實際上程序在執行的時候比這個負責,是會拷貝乙份父程序的資訊的)

frommultiprocessing import process

import time

def fun(n):

#dosomething

time.sleep(n)

print(n)if __name__ == "__main__":

p1= process(target=fun, args=(1,))

p2= process(target=fun, args=(2,))

p1.start()

p2.start()

p1.join()

p2.join()

七、總結

併發程式設計是我們提高程式效能的常用手段,一般來說就是多執行緒,多程序,協程,併發程式設計的時候,我們還有許多問題需要考慮,執行緒安全,通訊等等。

Spring Cloud 併發調優

測試介面 登入 鏈路呼叫 nginx zuul server servicea,serviceb,servicec,serviced 因為登入介面牽涉到一系列的加密校驗 許可權角色 賬號密碼驗證,所以 zuul server 路由之後,會呼叫很多個微服務來獲取使用者資訊。伺服器的話都是用docker...

多執行緒高併發調優

1.首先理解幾個多執行緒的概念 1 執行緒安全 保證執行緒的排程順序不變,以免引起資料不一致問題 2 執行緒同步 幾個執行緒協調同步,當幾個執行緒共享同乙份資源時,調整執行順序,當前乙個執行緒完成時,再執行下乙個 3 何為高併發 指程式在短時間內集中處理大量操作的情況,現實場景如 秒殺活動,搶票活動...

CPU調優併發問題

多核cpu 讓指定的程式 在指定的cpu上執行 看的是程序型別 cpu消耗型 i o消耗型 多執行緒併發 乙個程式執行 我使用到兩個cpu核心 我們可以讓改程式以執行緒方式執行 每 個核心執行乙個執行緒 多核情況下以執行緒方式執行效果更好一些,單核的話區別就不大了 測試 io消耗型 bin bash...