好湿?好紧?好多水好爽自慰,久久久噜久噜久久综合,成人做爰A片免费看黄冈,机机对机机30分钟无遮挡

主頁(yè) > 知識(shí)庫(kù) > Python threading Local()函數(shù)用法案例詳解

Python threading Local()函數(shù)用法案例詳解

熱門標(biāo)簽:鶴壁手機(jī)自動(dòng)外呼系統(tǒng)違法嗎 高德地圖標(biāo)注收入咋樣 萊蕪電信外呼系統(tǒng) B52系統(tǒng)電梯外呼顯示E7 沈陽(yáng)防封電銷電話卡 怎么辦理400客服電話 企業(yè)微信地圖標(biāo)注 地圖標(biāo)注多個(gè) 銀川電話機(jī)器人電話

前言

當(dāng)多線程訪問(wèn)同一個(gè)公共資源時(shí),如果涉及到修改該公共資源的操作就可能會(huì)出現(xiàn)由于數(shù)據(jù)不同步導(dǎo)致的線程安全問(wèn)題。一般情況下我們可以通過(guò)給公共資源加互斥鎖的方式來(lái)處理該問(wèn)題。

當(dāng)然,除非必須將多線程使用的資源設(shè)置為公共資源的情況。如果一個(gè)資源不需要在多個(gè)線程之間共享。我們也可以使用Python threading模塊提供的local()方式來(lái)避免線程安全問(wèn)題。
Python threading模塊的local()函數(shù)跟Java中的ThreadLocal類有諸多類似的地方,感興趣的小伙伴可以看下Java版的ThreadLoalJava ThreadLocal原理解析以及應(yīng)用場(chǎng)景分析案例詳解

local() 函數(shù)是什么?

threading的local()函數(shù)主要是用來(lái)封裝公共資源,使得同一個(gè)公共資源在不同線程之間得以隔離。這句話該如何理解呢?舉個(gè)例子說(shuō)明下!假設(shè)現(xiàn)在有一個(gè)大箱子(相當(dāng)于公共資源),每個(gè)人(相當(dāng)于各個(gè)線程)將自己的手機(jī)放入這個(gè)大箱子里。如果不做任何控制的話,當(dāng)人們從大箱子中取出手機(jī)時(shí)極有可能會(huì)出現(xiàn)取錯(cuò)的情況(找不到自己當(dāng)初放入的手機(jī))。而使用local()函數(shù)的話,就相當(dāng)于對(duì)這個(gè)大箱子進(jìn)行管理。當(dāng)每個(gè)人放入手機(jī)的時(shí)候做一個(gè)標(biāo)記(比如在手機(jī)上標(biāo)記所有者的姓名)并隔離放置到箱子中。這樣當(dāng)人們從大箱子中取出手機(jī)就能準(zhǔn)確的找到自己當(dāng)初放入的手機(jī)。

調(diào)用local()函數(shù)會(huì)生成一個(gè)ThreadLocal對(duì)象,該對(duì)象是所有線程都能訪問(wèn)的,就像上面例子中的大箱子。但是,放入到ThreadLocal對(duì)象中的變量則是各個(gè)線程所獨(dú)有的,隨便變量名相同,但是指向的值則是完全不同的。

local()函數(shù)如何用?

local()函數(shù)使用的基本語(yǔ)法是:

import threading

local=threading.local()

第一步就是引入threading模塊,第二步就是調(diào)用local()函數(shù)得到全局的Threadlocal對(duì)象。這樣說(shuō)始終是有點(diǎn)干澀,沒(méi)味道。那么就給代碼加點(diǎn)鹽吧。還是從那個(gè)大箱子說(shuō)起。

1. 不做標(biāo)記,不做隔離

第一個(gè)示例代碼就是所有人將自己的手機(jī)放入大箱子里,不做標(biāo)記,不做隔離。先放入,過(guò)一段時(shí)間后再取出。

import threading
import time


def set_telephone(telephone):
    global global_telephone
    global_telephone = telephone
    print(threading.current_thread().name + " 放入的手機(jī)是", global_telephone)
    time.sleep(1)
    get_telephone()


def get_telephone():
    print(threading.current_thread().name + " 取出的手機(jī)是", global_telephone)


if __name__ == '__main__':
    for i in range(3):
        thread = threading.Thread(target=set_telephone, name='學(xué)生' + str(i), args=('手機(jī)' + str(i),))
        thread.start()

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

學(xué)生0 放入的手機(jī)是 手機(jī)0

學(xué)生1 放入的手機(jī)是 手機(jī)1

學(xué)生2 放入的手機(jī)是 手機(jī)2

學(xué)生0 取出的手機(jī)是 手機(jī)2

學(xué)生1 取出的手機(jī)是 手機(jī)2

學(xué)生2 取出的手機(jī)是 手機(jī)2

這里有三個(gè)線程,分別模擬學(xué)生0,學(xué)生1,學(xué)生2 將各種的手機(jī)賦值給一個(gè)全局變量global_telephone(大箱子),然后取全局變量global_telephone中的值。可以看出取出的結(jié)果都變成了手機(jī)2。這顯然沒(méi)有達(dá)到我們的預(yù)期結(jié)果。這就是不加控制的后果。

2.使用local()函數(shù)加以控制

使用local()函數(shù)控制的話,就是將全局變量替換成ThreadLoal對(duì)象,由他來(lái)管理每個(gè)線程中的值。

import threading
import time


def set_telephone(telephone):
    local.telephone = telephone
    print(threading.current_thread().name + " 放入的手機(jī)是", local.telephone + "\n")
    time.sleep(1)
    get_telephone()


def get_telephone():
    print(threading.current_thread().name + " 取出的手機(jī)是", local.telephone + "\n")


if __name__ == '__main__':
    local = threading.local()
    for i in range(3):
        thread = threading.Thread(target=set_telephone, name='學(xué)生' + str(i), args=('手機(jī)' + str(i),))
        thread.start()

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

學(xué)生0 放入的手機(jī)是 手機(jī)0

學(xué)生1 放入的手機(jī)是 手機(jī)1

學(xué)生2 放入的手機(jī)是 手機(jī)2

學(xué)生1 取出的手機(jī)是 手機(jī)1

學(xué)生0 取出的手機(jī)是 手機(jī)0

學(xué)生2 取出的手機(jī)是 手機(jī)2

可以看出每個(gè)學(xué)生放入的手機(jī)和最終取出的手機(jī)是一致的。那么threading的local()函數(shù)是如何實(shí)現(xiàn)這一效果的呢?我們?cè)谶@里不妨做一個(gè)推理。應(yīng)該是將手機(jī)和它的主人做了一層映射關(guān)系。根據(jù)主人的唯一標(biāo)識(shí)來(lái)尋找自己的手機(jī)。

3. 模擬實(shí)現(xiàn)local()的功能,創(chuàng)建一個(gè)箱子

前面我們推測(cè)我們需要定義一個(gè)全局的字典來(lái)存放每個(gè)學(xué)生各自放入的手機(jī),字典的鍵是線程ID,值是指定的鍵值對(duì)。示例代碼如下:

import threading
import time

global_goods_dict = {}

# {
#     "線程ID":{"telephone":"放入的具體手機(jī)"},
#     "線程ID":{"telephone":"放入的具體手機(jī)"},
#     "線程ID":{"telephone":"放入的具體手機(jī)"}
#
# }

def set_telephone(telephone):
    # 獲取線程ID
    thread_id = threading.get_ident()
    global_goods_dict[thread_id] = {}
    global_goods_dict[thread_id]["telephone"] = telephone
    print(threading.current_thread().name + " 放入的手機(jī)是", telephone)
    time.sleep(1)
    get_telephone()


def get_telephone():
    thread_id = threading.get_ident()
    print(threading.current_thread().name + " 取出的手機(jī)是", global_goods_dict[thread_id]["telephone"])


if __name__ == '__main__':
    for i in range(3):
        thread = threading.Thread(target=set_telephone, name='學(xué)生' + str(i), args=('手機(jī)' + str(i),))
        thread.start()

運(yùn)行結(jié)果同上,這里定義了一個(gè)全局的字典global_goods_dict,字典的鍵盤是線程ID,這就保證了每個(gè)線程只能取到自己設(shè)置的數(shù)據(jù)。字典的值同樣是一個(gè)字典。這是因?yàn)橐粋€(gè)線程的要存的值可能不止一個(gè)。這里的global_goods_dict[thread_id]["telephone"] = telephone 就等價(jià)于上例中的local.telephone = telephone。這樣使用雖然能達(dá)到效果,但是使用起來(lái)還是有點(diǎn)繁瑣。那么能不能想local()函數(shù)那樣使用起來(lái)絲滑呢。

4. 簡(jiǎn)化代碼操作,進(jìn)一步模擬實(shí)現(xiàn)local()函數(shù)

我們可以將全局的global_goods_dict字典用一個(gè)類封裝到一個(gè)類中。讓該類在自動(dòng)的設(shè)置值

class MyBox:
    box = {}

    def __setattr__(self, key, value):
        thread_id = threading.get_ident()
        # 單元格已存在
        if thread_id in MyBox.box:
            MyBox.box[thread_id][key] = value
        else:
            MyBox.box[thread_id] = {key: value}

    def __getattr__(self, item):
        thread_id = threading.get_ident()
        return MyBox.box[thread_id][item]


def set_telephone(telephone):
    myBox.telephone = telephone
    print(threading.current_thread().name + " 放入的手機(jī)是", myBox.telephone + "\n")
    time.sleep(1)
    get_telephone()


def get_telephone():
    print(threading.current_thread().name + " 取出的手機(jī)是", myBox.telephone + "\n")


if __name__ == '__main__':
    myBox = MyBox()
    for i in range(3):
        thread = threading.Thread(target=set_telephone, name='學(xué)生' + str(i), args=('手機(jī)' + str(i),))
        thread.start()

運(yùn)行結(jié)果同上。這里通過(guò)MyBox類封裝了一個(gè)名為box的字典。該字典的鍵是當(dāng)前線程ID,值是賦值的變量名以及值組成的鍵值對(duì)。當(dāng)執(zhí)行set_telephone方法的myBox.telephone = telephone
,實(shí)際上會(huì)調(diào)用MyBox的__setattr__方法,參數(shù)key是telephone,參數(shù)value是"手機(jī)xx"。當(dāng)調(diào)用myBox.telephone時(shí)實(shí)際上會(huì)調(diào)用__getattr__方法,傳入的參數(shù)item是telephone。取值時(shí)首先獲取當(dāng)前線程ID。

總結(jié)

本文從實(shí)際例子出發(fā)詳細(xì)介紹了threading模塊的local()函數(shù)的使用。

到此這篇關(guān)于Python threading Local()函數(shù)用法案例詳解的文章就介紹到這了,更多相關(guān)Python threading Local()函數(shù)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

您可能感興趣的文章:
  • Python threading.local代碼實(shí)例及原理解析
  • python語(yǔ)言線程標(biāo)準(zhǔn)庫(kù)threading.local解讀總結(jié)
  • python threading模塊的使用指南
  • Python中threading庫(kù)實(shí)現(xiàn)線程鎖與釋放鎖
  • python中threading和queue庫(kù)實(shí)現(xiàn)多線程編程

標(biāo)簽:葫蘆島 湘西 三亞 呼倫貝爾 銀川 呼倫貝爾 安慶 烏魯木齊

巨人網(wǎng)絡(luò)通訊聲明:本文標(biāo)題《Python threading Local()函數(shù)用法案例詳解》,本文關(guān)鍵詞  Python,threading,Local,函數(shù),;如發(fā)現(xiàn)本文內(nèi)容存在版權(quán)問(wèn)題,煩請(qǐng)?zhí)峁┫嚓P(guān)信息告之我們,我們將及時(shí)溝通與處理。本站內(nèi)容系統(tǒng)采集于網(wǎng)絡(luò),涉及言論、版權(quán)與本站無(wú)關(guān)。
  • 相關(guān)文章
  • 下面列出與本文章《Python threading Local()函數(shù)用法案例詳解》相關(guān)的同類信息!
  • 本頁(yè)收集關(guān)于Python threading Local()函數(shù)用法案例詳解的相關(guān)信息資訊供網(wǎng)民參考!
  • 推薦文章
    主站蜘蛛池模板: 继h女乱h| 五月激情婷婷综合| 99久久网站| 轻轻操影院| 黑寡妇导航| 《乳色吐息》樱花免费看| 日韩人成| 亚洲欧美一区二区久久香蕉| Big丰满大白屁ss4| 秘书大胸奶头晃着喷奶水| 抵在洗手台挺进撞击h| 2012中文字幕在线中文字幕小说| 女人脱了内裤趴开腿让男躁动漫 | 免费国产h视频在线观看| 穿成校园文的炮灰男配| 免费无码婬A片在线视频夜网站| 欧美高潮呻吟久久AV无码下载 | 三上悠亚AV一区二区视频| 扶余县| 不用付费就可以看亏亏网站| 大伊香蕉精品视频在线观看 | 做爰???视频毛片下载蜜桃视频| 亚洲另类天堂| 美女动态啪啪图| 国内精品一级毛片免费看| 国产黑丝在线播放| 欲求不满的人妻另类一级吖| 男男主奴胯下裸跪调教vk| 刺激花蒂抽搐视频在线看| 久久久久精品国产亚洲AV妓女 | 18chinese摸醉酒直男1| 91人妻精品国产一区二区| 91sao国产在线观看| 精品国产毛片| 机机对机机30秒无遮挡软件| 师尊从小给女婴罐精h女配逆袭| 飘雪影院在线观看免费完整版高清 | 日本人做爰大片免费| 亚洲一区二区网站| 深夜福利试看| 91欧美精品|