學習三把鎖時候我們需要先知道為什麼要有三把鎖
全域性資源(counter)被搶占的情況,問題產生的原因就是沒有控制多個執行緒對同一資源的訪問,對資料造成破壞,使得執行緒執行的結果不可預期。這種現象稱為「執行緒不安全」。在開發過程中我們必須要避免這種情況,那怎麼避免?這就用到了我們在綜述中提到的互斥鎖了。
互斥鎖概念
python程式設計中,引入了物件互斥鎖的概念,來保證共享資料操作的完整性。每個物件都對應於乙個可稱為」 互斥鎖」 的標記,這個標記用來保證在任一時刻,只能有乙個執行緒訪問該物件。在python中我們使用threading模組提供的lock類。
我們對上面的程式進行整改,為此我們需要新增乙個互斥鎖變數mutex = threading.lock(),然後在爭奪資源的時候之前我們會先搶占這把鎖mutex.acquire(),對資源使用完成之後我們在釋放這把鎖mutex.release()。**如下:
import threadingimport 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);
ifmutex.acquire():#判斷是否存在程序鎖
counter += 1
"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()
在threading模組中,定義兩種型別的瑣:threading.lock和threading.rlock。它們之間有一點細微的區別,通過比較下面兩段**來說明:
import threadinglock =threading.lock() #lock物件
lock
.acquire()
lock
.acquire() #產生了死瑣。
lock
.release()
lock
.release()
列印結果:會出現無法執行下去
import threading
rlock =threading.rlock() #rlock物件
rlock.acquire()
rlock.acquire() #在同一執行緒內,程式不會堵塞。
rlock.release()
rlock.release()
這兩種瑣的主要區別是:rlock允許在同一執行緒中被多次acquire。而lock卻不允許這種情況。注意:如果使用rlock,那麼acquire和release必須成對出現,即呼叫了n次acquire,必須呼叫n次的release才能真正釋放所占用的瑣。threading.condition
可以把condiftion理解為一把高階的瑣,它提供了比lock, rlock更高階的功能,允許我們能夠控制複雜的執行緒同步問題。threadiong.condition在內部維護乙個瑣物件(預設是rlock),可以在建立condigtion物件的時候把瑣物件作為引數傳入。condition也提供了acquire, release方法,其含義與瑣的acquire, release方法一致,其實它只是簡單的呼叫內部瑣物件的對應的方法而已。condition還提供了如下方法(特別要注意:這些方法只有在占用瑣(acquire)之後才能呼叫,否則將會報runtimeerror異常。):
################這個方法作為補充######################
condition.wait([timeout]):
wait方法釋放內部所占用的瑣,同時執行緒被掛起,直至接收到通知被喚醒或超時(如果提供了timeout引數的話)。當執行緒被喚醒並重新占有瑣的時候,程式才會繼續執行下去。
condition.notify():
喚醒乙個掛起的執行緒(如果存在掛起的執行緒)。注意:notify()方法不會釋放所占用的瑣。
condition.notify_all()
condition.notifyall()
喚醒所有掛起的執行緒(如果存在掛起的執行緒)。注意:這些方法不會釋放所占用的瑣。
semaphore管理乙個內建的計數器,
每當呼叫acquire()時內建計數器-1;
呼叫release() 時內建計數器+1;
計數器不能小於0;當計數器為0時,acquire()將阻塞執行緒直到其他執行緒呼叫release()。
#! /usr/bin/env pythonthread-1get semaphore# -*- coding: utf-8 -*-
# __author__ = "wyd"
# date: 2017/7/18
import threading
import time
semaphore= threading.semaphore(5)#這裡我們只允許同時執行5個執行緒
def fun():
if semaphore.acquire():#這裡我們占用呼叫一把鎖原來的可使用鎖數-1
print(threading.currentthread().getname()+'get semaphore')#threading.currentthread().getname()檢視使用的執行緒列印結果
time.sleep(0.5)
semaphore.release()
for i in range(20):#這裡我們開啟20個執行緒
t1=threading.thread(target=fun)
t1.start()
***********************************====列印的結果**********===
thread-2get semaphore
thread-3get semaphore
thread-4get semaphore
thread-5get semaphore
執行緒8把鎖
一 題目 判斷列印的 one or two 1.兩個普通同步方法,兩個執行緒,標準列印,列印?one two 2.新增 thread.sleep 給 getone 列印?one two 3.新增普通方法 getthree 列印?three one two 4.兩個普通同步方法,兩個 number 物...
python執行緒鎖 守護執行緒,程序鎖 守護程序
1 守護程序 1.1 什麼是守護程序?1 守護程序會在主程序 執行結束的情況下,立即結束。2 守護程序本身其實就是乙個子程序。3 主程序在其 結束後已經執行完畢 守護程序在此時就被 然後主程序會一直等非守護的子程序都執行完畢後 子程序的資源才會結束。1.2 為什麼要用守護程序?1 守護程序本身就是乙...
實驗三 程序與執行緒
一 實驗名稱 實驗三 程序與執行緒 二 實驗日期 2014 3 13 三 實驗目的 1.linux程序 2.簡單的程序同步 四 實驗的步驟和方法 實驗1 linux程序家族樹 檔名3 1 1.c 看程式寫結果。要求 增加1個fork 2個fork 多個fork 的結果會怎樣?並說明原因,找出規律。增...