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

Python多線程編程(四):使用Lock互斥鎖

 更新時(shí)間:2015年04月05日 11:32:30   投稿:junjie  
這篇文章主要介紹了Python多線程編程(四):使用Lock互斥鎖,本文講解了互斥鎖概念、同步阻塞、代碼示例等內(nèi)容,需要的朋友可以參考下

前面已經(jīng)演示了Python:使用threading模塊實(shí)現(xiàn)多線程編程二兩種方式起線程Python:使用threading模塊實(shí)現(xiàn)多線程編程三threading.Thread類的重要函數(shù),這兩篇文章的示例都是演示了互不相干的獨(dú)立線程,現(xiàn)在我們考慮這樣一個(gè)問題:假設(shè)各個(gè)線程需要訪問同一公共資源,我們的代碼該怎么寫?

復(fù)制代碼 代碼如下:

'''
Created on 2012-9-8
 
@author: walfred
@module: thread.ThreadTest3
''' 
import threading 
import time 
 
counter = 0 
 
class MyThread(threading.Thread): 
    def __init__(self): 
        threading.Thread.__init__(self) 
 
    def run(self): 
        global counter 
        time.sleep(1); 
        counter += 1 
        print "I am %s, set counter:%s" % (self.name, counter) 
 
if __name__ == "__main__": 
    for i in range(0, 200): 
        my_thread = MyThread() 
        my_thread.start()

解決上面的問題,我們興許會(huì)寫出這樣的代碼,我們假設(shè)跑200個(gè)線程,但是這200個(gè)線程都會(huì)去訪問counter這個(gè)公共資源,并對該資源進(jìn)行處理(counter += 1),代碼看起來就是這個(gè)樣了,但是我們看下運(yùn)行結(jié)果:

復(fù)制代碼 代碼如下:

I am Thread-69, set counter:64
I am Thread-73, set counter:66I am Thread-74, set counter:67I am Thread-75, set counter:68I am Thread-76, set counter:69I am Thread-78, set counter:70I am Thread-77, set counter:71I am Thread-58, set counter:72I am Thread-60, set counter:73I am Thread-62, set counter:74I am Thread-66,set counter:75I am Thread-70, set counter:76I am Thread-72, set counter:77I am Thread-79, set counter:78I am Thread-71, set counter:78

打印結(jié)果我只貼了一部分,從中我們已經(jīng)看出了這個(gè)全局資源(counter)被搶占的情況,問題產(chǎn)生的原因就是沒有控制多個(gè)線程對同一資源的訪問,對數(shù)據(jù)造成破壞,使得線程運(yùn)行的結(jié)果不可預(yù)期。這種現(xiàn)象稱為“線程不安全”。在開發(fā)過程中我們必須要避免這種情況,那怎么避免?這就用到了我們在綜述中提到的互斥鎖了。

互斥鎖概念

Python編程中,引入了對象互斥鎖的概念,來保證共享數(shù)據(jù)操作的完整性。每個(gè)對象都對應(yīng)于一個(gè)可稱為” 互斥鎖” 的標(biāo)記,這個(gè)標(biāo)記用來保證在任一時(shí)刻,只能有一個(gè)線程訪問該對象。在Python中我們使用threading模塊提供的Lock類。

我們對上面的程序進(jìn)行整改,為此我們需要添加一個(gè)互斥鎖變量mutex = threading.Lock(),然后在爭奪資源的時(shí)候之前我們會(huì)先搶占這把鎖mutex.acquire(),對資源使用完成之后我們在釋放這把鎖mutex.release()。代碼如下:

復(fù)制代碼 代碼如下:

'''
Created on 2012-9-8
 
@author: walfred
@module: thread.ThreadTest4
''' 
 
import threading 
import time 
 
counter = 0 
mutex = threading.Lock() 
 
class MyThread(threading.Thread): 
    def __init__(self): 
        threading.Thread.__init__(self) 
 
    def run(self): 
        global counter, mutex 
        time.sleep(1); 
        if mutex.acquire(): 
            counter += 1 
            print "I am %s, set counter:%s" % (self.name, counter) 
            mutex.release() 
 
if __name__ == "__main__": 
    for i in range(0, 100): 
        my_thread = MyThread() 
        my_thread.start()

同步阻塞

當(dāng)一個(gè)線程調(diào)用Lock對象的acquire()方法獲得鎖時(shí),這把鎖就進(jìn)入“l(fā)ocked”狀態(tài)。因?yàn)槊看沃挥幸粋€(gè)線程1可以獲得鎖,所以如果此時(shí)另一個(gè)線程2試圖獲得這個(gè)鎖,該線程2就會(huì)變?yōu)椤癰lo同步阻塞狀態(tài)。直到擁有鎖的線程1調(diào)用鎖的release()方法釋放鎖之后,該鎖進(jìn)入“unlocked”狀態(tài)。線程調(diào)度程序從處于同步阻塞狀態(tài)的線程中選擇一個(gè)來獲得鎖,并使得該線程進(jìn)入運(yùn)行(running)狀態(tài)。

進(jìn)一步考慮

通過對公共資源使用互斥鎖,這樣就簡單的到達(dá)了我們的目的,但是如果我們又遇到下面的情況:

遇到鎖嵌套的情況該怎么辦,這個(gè)嵌套是指當(dāng)我一個(gè)線程在獲取臨界資源時(shí),又需要再次獲??;
如果有多個(gè)公共資源,在線程間共享多個(gè)資源的時(shí)候,如果兩個(gè)線程分別占有一部分資源并且同時(shí)等待對方的資源;

上述這兩種情況會(huì)直接造成程序掛起,即死鎖,下面我們會(huì)談死鎖及可重入鎖RLock。

相關(guān)文章

  • Python機(jī)器學(xué)習(xí)應(yīng)用之基于LightGBM的分類預(yù)測篇解讀

    Python機(jī)器學(xué)習(xí)應(yīng)用之基于LightGBM的分類預(yù)測篇解讀

    這篇文章我們繼續(xù)學(xué)習(xí)一下GBDT模型的另一個(gè)進(jìn)化版本:LightGBM,LigthGBM是boosting集合模型中的新進(jìn)成員,由微軟提供,它和XGBoost一樣是對GBDT的高效實(shí)現(xiàn),原理上它和GBDT及XGBoost類似,都采用損失函數(shù)的負(fù)梯度作為當(dāng)前決策樹的殘差近似值,去擬合新的決策樹
    2022-01-01
  • 將不規(guī)則的Python多維數(shù)組拉平到一維的方法實(shí)現(xiàn)

    將不規(guī)則的Python多維數(shù)組拉平到一維的方法實(shí)現(xiàn)

    這篇文章主要介紹了將不規(guī)則的Python多維數(shù)組拉平到一維的方法實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-01-01
  • Python實(shí)現(xiàn)讀取文件最后n行的方法

    Python實(shí)現(xiàn)讀取文件最后n行的方法

    這篇文章主要介紹了Python實(shí)現(xiàn)讀取文件最后n行的方法,涉及Python針對文件的讀取、遍歷與運(yùn)算相關(guān)操作技巧,需要的朋友可以參考下
    2017-02-02
  • 定制FileField中的上傳文件名稱實(shí)例

    定制FileField中的上傳文件名稱實(shí)例

    下面小編就為大家?guī)硪黄ㄖ艶ileField中的上傳文件名稱實(shí)例。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2017-08-08
  • Python生成器之yield詳解

    Python生成器之yield詳解

    這篇文章主要介紹了Python生成器yield,yield除了作為生成器的標(biāo)志以外,還有一個(gè)「返回值」的功能,我們知道return也有這個(gè)功能,那么它跟return的這個(gè)返回值有什么區(qū)別呢,本文將詳細(xì)的介紹yield,需要的朋友可以參考下
    2023-05-05
  • Python入門教程5. 字典基本操作【定義、運(yùn)算、常用函數(shù)】

    Python入門教程5. 字典基本操作【定義、運(yùn)算、常用函數(shù)】

    這篇文章主要介紹了Python字典基本操作,包括字典的基本定義、運(yùn)算與常用函數(shù)相關(guān)使用技巧,代碼注釋中備有詳盡說明,便于理解,需要的朋友可以參考下
    2018-11-11
  • python 使用shutil復(fù)制圖片的例子

    python 使用shutil復(fù)制圖片的例子

    今天小編就為大家分享一篇python 使用shutil復(fù)制圖片的例子,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2019-12-12
  • 舉例講解Python中的身份運(yùn)算符的使用方法

    舉例講解Python中的身份運(yùn)算符的使用方法

    這篇文章主要介紹了舉例講解Python中的身份運(yùn)算符的使用方法,是Python入門學(xué)習(xí)中的基礎(chǔ)知識(shí),需要的朋友可以參考下
    2015-10-10
  • Python 列表list使用介紹

    Python 列表list使用介紹

    這篇文章主要介紹了Python 列表list使用介紹,需要的朋友可以參考下
    2014-11-11
  • VSCode搭建Django開發(fā)環(huán)境的圖文步驟

    VSCode搭建Django開發(fā)環(huán)境的圖文步驟

    本篇介紹在vscode環(huán)境下搭建Django開發(fā)環(huán)境的詳細(xì)步驟,包括Python、Django、VSCode等,以及它們的安裝和配置方法,具有一定的參考價(jià)值,感興趣的可以了解一下
    2023-09-09

最新評論