[Python 多線程] threading.local類 (六)

來源:互聯網
上載者:User

標籤:建立   most   就是   rac   targe   作用   error   ror   def   

 

在使用threading.local()之前,先瞭解一下局部變數和全域變數。

 

局部變數:

import threadingimport timedef worker():    x = 0    for i in range(100):        time.sleep(0.0001)        x += 1    print(threading.current_thread(),x)for i in range(10):    threading.Thread(target=worker).start()運行結果:<Thread(Thread-2, started 123145372971008)> 100<Thread(Thread-6, started 123145393991680)> 100<Thread(Thread-1, started 123145367715840)> 100<Thread(Thread-3, started 123145378226176)> 100<Thread(Thread-5, started 123145388736512)> 100<Thread(Thread-7, started 123145399246848)> 100<Thread(Thread-4, started 123145383481344)> 100<Thread(Thread-10, started 123145415012352)> 100<Thread(Thread-8, started 123145404502016)> 100<Thread(Thread-9, started 123145409757184)> 100

  上面例子使用多線程,每個子線程完成不同的計算任務,x是局部變數。

每個子線程都要壓棧,每個棧是獨立的空間。每次壓棧,局部變數x的範圍地址是不同的(線程獨享),計算結果互不干擾。

 

全域變數:

使用global:

import threadingimport timex = 0def worker():    global x    x = 0    for i in range(100):        time.sleep(0.0001)        x += 1    print(threading.current_thread(),x)for i in range(10):    threading.Thread(target=worker).start()運行結果:<Thread(Thread-2, started 123145483571200)> 888<Thread(Thread-5, started 123145499336704)> 908<Thread(Thread-3, started 123145488826368)> 930<Thread(Thread-4, started 123145494081536)> 937<Thread(Thread-1, started 123145478316032)> 941<Thread(Thread-6, started 123145504591872)> 947<Thread(Thread-7, started 123145509847040)> 949<Thread(Thread-8, started 123145515102208)> 955<Thread(Thread-9, started 123145520357376)> 962<Thread(Thread-10, started 123145525612544)> 964

  上面例子中當主線程中x是全域變數時,就變成了公用資源(也就是同一個對象),每個子線程互相干擾,最終導致錯誤的計算結果。

 

Python提供了 threading.local 類,將這個類執行個體化得到一個全域對象,但是不同的線程使用這個Object Storage Service的資料其它線程不可見(本質上就是不同的線程使用這個對象時為其建立一個獨立的字典)。

 

使用threading.local() :

import threadingimport time# class A:#     def __init__(self,x):#         self.x = x# a = A(0)a = threading.local()#全域對象def worker():    a.x = 0    for i in range(100):        time.sleep(0.0001)        a.x += 1    print(threading.current_thread(),a.x)for i in range(10):    threading.Thread(target=worker).start()運行結果:<Thread(Thread-4, started 123145570172928)> 100<Thread(Thread-6, started 123145580683264)> 100<Thread(Thread-1, started 123145554407424)> 100<Thread(Thread-2, started 123145559662592)> 100<Thread(Thread-8, started 123145591193600)> 100<Thread(Thread-5, started 123145575428096)> 100<Thread(Thread-3, started 123145564917760)> 100<Thread(Thread-7, started 123145585938432)> 100<Thread(Thread-10, started 123145601703936)> 100<Thread(Thread-9, started 123145596448768)> 100

  每個子線程使用全域對象a,但每個線程定義的屬性a.x是該線程專屬的。

 

舉一個錯誤的例子:,主線程中使用threading.local定義本地變數x,x在主線程中是專屬的,子線程中就訪問不到主線程的x的屬性。

import threadingX=‘abc‘ctx=threading.local()ctx.x=123 #主線程中定義x區域屬性print(ctx,type(ctx),ctx.x)def work():    print(X)    print(ctx)    print(ctx.x) #子線程訪問不到    print(‘Good job‘)threading.Thread(target=work).start()運行結果:<_thread._local object at 0x10407bd00> <class ‘_thread._local‘> 123abc<_thread._local object at 0x10407bd00>Exception in thread Thread-1:Traceback (most recent call last):  File "/Users/ihoney/Python/test_4.py", line 12, in work    print(ctx.x)AttributeError: ‘_thread._local‘ object has no attribute ‘x‘

  ctx全域對象對主線程和子線程都是可以使用的,主線程定義了屬性x,但子線程在嘗試訪問屬性x時,就相當於訪問自己線程內的屬性x,而自己線程並沒有定義,就會拋出AttributeError異常:‘_thread._local‘ object has no attribute ‘x‘。

 

[Python 多線程] threading.local類 (六)

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.