第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

全部開(kāi)發(fā)者教程

Python 進(jìn)階應(yīng)用教程

Python 進(jìn)階應(yīng)用教程
01 Python 的對(duì)象和類 02 Python 類屬性和實(shí)例屬性 03 Python類的構(gòu)造方法、析構(gòu)方法、實(shí)例方法 04 Python 類的私有屬性和私有方法 05 Python 類的繼承和多繼承 06 Python 類實(shí)戰(zhàn) 07 Python 中的迭代器實(shí)現(xiàn)原理 08 Python 中的迭代器趣味實(shí)踐 09 Python 中的生成器實(shí)現(xiàn)原理 10 Python 中的生成器趣味實(shí)踐 11 Python 中的錯(cuò)誤和異常 12 Python 中的異常處理 13 Python 中的模塊 14 Python 標(biāo)準(zhǔn)庫(kù)之 os 模塊 15 Python 標(biāo)準(zhǔn)庫(kù)之 sys 模塊 16 Python 標(biāo)準(zhǔn)庫(kù)之 math 模塊 17 Python 標(biāo)準(zhǔn)庫(kù)之 random 模塊 18 Python 標(biāo)準(zhǔn)庫(kù)之 Json 模塊 19 Python 標(biāo)準(zhǔn)庫(kù) datetime 模塊 20 Python 中的常用第三方模塊 21 Python 中的命名空間 22 Python 中的作用域 23 Python 中的文件 IO 操作 24 Python 基礎(chǔ)實(shí)戰(zhàn) 25 Python 內(nèi)置函數(shù) 26 Python 中使用正則表達(dá)式 27 使用 Python 操作 MySQL 數(shù)據(jù)庫(kù) 28 使用 Python 操作 Mongo 數(shù)據(jù)庫(kù) 29 使用 Python 操作 Redis 數(shù)據(jù)庫(kù) 30 使用 Python 發(fā)送一封郵件 31 threading 之 Thread 的使用 32 threading 之 Lock 的基本使用 33 Python 生產(chǎn)者消費(fèi)者模型 34 Python 的內(nèi)存管理與垃圾回收 35 Python 領(lǐng)域運(yùn)用:網(wǎng)絡(luò)爬蟲(chóng) 36 Python 領(lǐng)域運(yùn)用:Web 開(kāi)發(fā) 37 Python 領(lǐng)域運(yùn)用:自動(dòng)化運(yùn)維 38 Python 領(lǐng)域運(yùn)用:自動(dòng)化測(cè)試

threading 模塊的類 Lock 的基本使用

1. 簡(jiǎn)介

在多線程應(yīng)用中,某個(gè)資源被多個(gè)線程共享訪問(wèn),線程通過(guò)使用鎖獨(dú)占該資源。需要獨(dú)占訪問(wèn)的資源可能是:

  • 打印機(jī),線程在使用打印機(jī)時(shí),不允許其它線程向打印機(jī)輸出
  • 共享變量,線程對(duì)這個(gè)變量進(jìn)行讀取訪問(wèn)時(shí),不允許其它線程同時(shí)對(duì)這個(gè)變量進(jìn)行讀取訪問(wèn)

python 的 threading 模塊提供了類 Lock 用于獨(dú)占訪問(wèn)某個(gè)共享資源,類 Lock 提供了如下方法:

方法 功能
acquire() 獲得鎖,如果鎖是空閑的,則立即返回;如果鎖已經(jīng)被其它線程占用了,則阻塞等待。
release() 釋放鎖,喚醒等待該鎖的線程。

線程在獨(dú)占使用某個(gè)資源前,需要調(diào)用 lock.acquire() 方法,使用完畢后,需要調(diào)用 lock.release() 方法,如下所示:

lock = threading.Lock()

lock.acquire()
獨(dú)占訪問(wèn)某個(gè)資源
lock.release()

2. 數(shù)據(jù)競(jìng)爭(zhēng)

當(dāng)多個(gè)線程在讀寫(xiě)某個(gè)共享變量時(shí),其最終的結(jié)果依賴于線程的執(zhí)行順序,這種現(xiàn)象被稱為數(shù)據(jù)競(jìng)爭(zhēng),示例如下:

import threading

sum = 0
tmp = 0
  • 引入模塊 threading
  • 設(shè)定全局變量 sum 和 tmp 的初值為 0,它們被線程共享訪問(wèn)
def thread_entry():
    global sum, tmp

    for i in range(1000 * 1000):
        tmp = sum + 1
        sum = tmp
  • 在第 1 行,定義線程入口 thread_entry
  • 在第 2 行,聲明共享變量 sum 和 tmp
  • 在第 4 行,for 循環(huán) 1000* 1000 次,遞增變量 sum
t0 = threading.Thread(target = thread_entry, args = ())
t1 = threading.Thread(target = thread_entry, args = ())
t0.start()
t1.start()
t0.join()
t1.join()
print('sum =', sum)
  • 創(chuàng)建線程 t0,線程入口為 thread_entry
    • 線程 t0 對(duì)變量 sum 遞增 1000 * 1000 次
  • 創(chuàng)建線程 t1,線程入口為 thread_entry
    • 線程 t1 對(duì)變量 sum 遞增 1000 * 1000 次
  • 等待兩個(gè)線程結(jié)束后,打印 sum 的值

第一次運(yùn)行程序,輸出結(jié)果如下:

sum = 1464661

再次運(yùn)行程序,輸出結(jié)果如下:

sum = 1415592

線程 t0 和 t1 對(duì) sum 各自遞增 1000 * 1000 次,期望最終的 sum 為 2 * 1000 * 1000。然而,線程 t0 和 線程 t1 共享訪問(wèn)變量 sum 和 tmp,存在數(shù)據(jù)競(jìng)爭(zhēng),導(dǎo)致:

  • 實(shí)際結(jié)果依賴于線程的執(zhí)行順序,每次執(zhí)行程序的輸出結(jié)果都不一樣
  • 實(shí)際結(jié)果和預(yù)期不一致

3. 使用 lock 防止數(shù)據(jù)競(jìng)爭(zhēng)

可以使用 threading 模塊的類 Lock 防止數(shù)據(jù)競(jìng)爭(zhēng),示例如下:

import threading

sum = 0
tmp = 0

def thread_entry():
    global sum, tmp

    for i in range(1000 * 1000):
        lock.acquire()  # 獲取鎖
        tmp = sum + 1
        sum = tmp
        lock.release()  # 釋放鎖

lock = threading.Lock() # 初始化鎖
t0 = threading.Thread(target = thread_entry, args = ())
t1 = threading.Thread(target = thread_entry, args = ())
t0.start()
t1.start()
t0.join()
t1.join()
print('sum =', sum)

和上個(gè)小節(jié)的例子相比,增加了 3 行代碼 (使用注釋標(biāo)記):

  • lock.acquire(),訪問(wèn)共享變量 sum 和 tmp 前,需要獲取鎖
  • lock.release(),訪問(wèn)共享變量 sum 和 tmp 后,需要釋放鎖
  • lock = thread.Lock(),初始化鎖

第一次運(yùn)行程序,輸出結(jié)果如下:

sum = 200000

再次運(yùn)行程序,輸出結(jié)果如下:

sum = 200000

線程 t0 和 t1 對(duì) sum 各自遞增 1000 * 1000 次,期望最終的 sum 為 2 * 1000 * 1000。使用了 lock 防止了數(shù)據(jù)競(jìng)爭(zhēng):

  • 每次執(zhí)行程序的輸出結(jié)果都是相同的
  • 實(shí)際結(jié)果和期望結(jié)果相符合