摘要:為了避免改亂為,我們?cè)谇懊嬉呀?jīng)提到說(shuō)要加鎖。僅供一個(gè)線程使用,線程間相互不影響。例如下列程序中函數(shù)中定義的變量就是局部變量。所有綁定的參數(shù)都是線程隔離的。下面展示一下代碼創(chuàng)建一個(gè)全局的對(duì)象初始化一個(gè)線程內(nèi)變量,該變量線程間互不影響。
我們?cè)诰帉懚嗑€程程序的時(shí)候,往往會(huì)遇到兩種類型的變量。
一種是全局變量,多個(gè)線程共享。為了避免改亂為,我們?cè)谇懊嬉呀?jīng)提到說(shuō)要加鎖。
一種是局部變量。僅供一個(gè)線程使用,線程間相互不影響。
例如下列程序中task()函數(shù)中定義的count變量就是局部變量。即使我們創(chuàng)建了兩個(gè)線程,兩者的count遞增也不會(huì)相互影響,因?yàn)?b>count是在task中定義的。
import threading def task(): count = 0 for i in range(1000): count += 1 print count if __name__ == "__main__": t1 = threading.Thread(target=task) t1.start() t2 = threading.Thread(target=task) t2.start()
那么,這么處理是不是就完美了呢?其實(shí)還不是。
以上的例子我們舉的是一個(gè)非常簡(jiǎn)單的例子,但是我們遇到一個(gè)比較復(fù)雜的業(yè)務(wù)邏輯的時(shí)候,比如多個(gè)局部變量,函數(shù)多重調(diào)用等,這么定義局部變量就會(huì)變得不簡(jiǎn)潔,麻煩。
函數(shù)多重調(diào)用是指,例如:
我們定義了函數(shù),methodA(),這個(gè)方法體內(nèi)調(diào)用了methodB(), methodB()方法體中又調(diào)用了methodC()...
如果我們?cè)谀骋粋€(gè)線程中調(diào)用了methodA()并且使用了一個(gè)變量attr,那么我們就需要將attr一層一層地傳遞給后續(xù)的函數(shù)。
有沒(méi)有一種方法,能讓我們?cè)诰€程中定義一個(gè)變量后,那么這個(gè)線程中的函數(shù)就都能調(diào)用,如此才叫簡(jiǎn)潔明了?
Python為我們做到了,那就是ThreadLocal.
ThreadLocal的用法只需要三步:
定義一個(gè)對(duì)象 threading.local
在線程內(nèi)給該對(duì)象綁定參數(shù)。所有綁定的參數(shù)都是線程隔離的。
在線程內(nèi)調(diào)用。
下面展示一下代碼:
# coding=utf-8 import threading local = threading.local() # 創(chuàng)建一個(gè)全局的對(duì)象 def task(): local.count = 0 # 初始化一個(gè)線程內(nèi)變量,該變量線程間互不影響。 for i in range(1000): count_plus() def count_plus(): local.count += 1 print threading.current_thread().name, local.count if __name__ == "__main__": t1 = threading.Thread(target=task) t1.start() t2 = threading.Thread(target=task) t2.start()
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/38436.html
摘要:底層是一個(gè)的散列表可擴(kuò)容的數(shù)組,并采用開放地址法來(lái)解決沖突。稍后討論方法每個(gè)對(duì)象都有一個(gè)值,每初始化一個(gè)對(duì)象,值就增加一個(gè)固定的大小。因此在使用的時(shí)候要手動(dòng)調(diào)用方法,防止內(nèi)存泄漏。 ThreadLocal定義 先看JDK關(guān)于ThreadLocal的類注釋: This class provides thread-local variables. These variables diffe...
摘要:通過(guò)向消息池發(fā)送各種消息事件通過(guò)處理相應(yīng)的消息事件。子線程往消息隊(duì)列發(fā)送消息,并且往管道文件寫數(shù)據(jù),主線程即被喚醒,從管道文件讀取數(shù)據(jù),主線程被喚醒只是為了讀取消息,當(dāng)消息讀取完畢,再次睡眠。 目錄介紹 6.0.0.1 談?wù)勏C(jī)制Hander作用?有哪些要素?流程是怎樣的? 6.0.0.2 為什么一個(gè)線程只有一個(gè)Looper、只有一個(gè)MessageQueue,可以有多個(gè)Handle...
摘要:在深入理解中的變量上中我們看到的引入,使得可以很方便地在多線程環(huán)境中使用局部變量。特別需要注意的是,基類的并不會(huì)屏蔽派生類中的創(chuàng)建。到此,整個(gè)源碼核心部分已經(jīng)理解的差不多了,只剩下用來(lái)執(zhí)行清除工作。 在 深入理解Python中的ThreadLocal變量(上) 中我們看到 ThreadLocal 的引入,使得可以很方便地在多線程環(huán)境中使用局部變量。如此美妙的功能到底是怎樣實(shí)現(xiàn)的?如果你...
摘要:在子線程中發(fā)送消息,主線程接受到消息并且處理邏輯。子線程往消息隊(duì)列發(fā)送消息,并且往管道文件寫數(shù)據(jù),主線程即被喚醒,從管道文件讀取數(shù)據(jù),主線程被喚醒只是為了讀取消息,當(dāng)消息讀取完畢,再次睡眠。 目錄介紹 1.Handler的常見的使用方式 2.如何在子線程中定義Handler 3.主線程如何自動(dòng)調(diào)用Looper.prepare() 4.Looper.prepare()方法源碼分析 5....
摘要:具體怎么實(shí)現(xiàn)的呢,思想其實(shí)特別簡(jiǎn)單,我們?cè)谏钊肜斫庵械淖兞可弦晃牡淖詈笥刑崞疬^(guò),就是創(chuàng)建一個(gè)全局字典,然后將線程或者協(xié)程標(biāo)識(shí)符作為,相應(yīng)線程或協(xié)程的局部數(shù)據(jù)作為。 在上篇我們看到了 ThreadLocal 變量的簡(jiǎn)單使用,中篇對(duì)python中 ThreadLocal 的實(shí)現(xiàn)進(jìn)行了分析,但故事還沒(méi)有結(jié)束。本篇我們一起來(lái)看下Werkzeug中ThreadLocal的設(shè)計(jì)。 Werkzeug...
閱讀 1905·2021-11-24 11:16
閱讀 3261·2021-09-10 10:51
閱讀 3201·2021-08-03 14:03
閱讀 1266·2019-08-29 17:03
閱讀 3245·2019-08-29 12:36
閱讀 2233·2019-08-26 14:06
閱讀 497·2019-08-23 16:32
閱讀 2679·2019-08-23 13:42