[Python]threading local 線程局部變數小測試,pythonthreading

來源:互聯網
上載者:User

[Python]threading local 線程局部變數小測試,pythonthreading
概念     

有個概念叫做線程局部變數,一般我們對多線程中的全域變數都會加鎖處理,這種變數是共用變數,每個線程都可以讀寫變數,為了保持同步我們會做枷鎖處理。但是有些變數初始化以後,我們只想讓他們在每個線程中一直存在,相當於一個線程內的共用變數,線程之間又是隔離的。python threading模組中就提供了這麼一個類,叫做local。


多線程中共用變數和局部變數的區別我畫兩個小圖,簡單描述下(作圖能力一般,請見諒,概念性的東西大家可以google下,很多好文章)


全域變數



線程局部變數



對比:

下面是3個小例子,分別是使用local局部變數, 全域變數, gevent中的local來看線程對變數的操作是否隔離。

#!/usr/bin/python# -*- coding: utf-8 -*-# python2.7x# author: orangelliu# date: 2014-08-20'''執行緒區域變數  初始值定義之後,線上程中可以保持隔離性為了做對比,分別和全域變數,gevent線程對比線程局部變數'''from time import sleepfrom random import randomfrom threading import Thread, localdata = local()def bar():    print 'called from %s'%data.vdef foo():    data.v = str(data.v) + '.......'    bar()class T(Thread):    def run(self):        sleep(random())        data.v = self.getName()        sleep(1)        foo()T().start()T().start()

執行結果:

called from Thread-1.......
called from Thread-2.......
[Finished in 1.6s]

可以看到每個v只在自己的線程中操作。


#!/usr/bin/python# -*- coding: utf-8 -*-# python2.7x# author: orangelliu# date: 2014-08-20'''執行緒區域變數  初始值定義之後,線上程中可以保持隔離性為了做對比,分別和全域變數,gevent線程對比全域變數'''from time import sleepfrom random import randomfrom threading import Thread, local#如果使用全域變數呢def bar1():    global v    print 'calledddddd from %s'%vdef foo1():    global v    v = v + '.....'    bar1()class T1(Thread):    def run(self):        global v        sleep(random())        v =self.getName()        sleep(1)        foo1()T1().start()T1().start()

執行結果:

calledddddd from Thread-1.....
calledddddd from Thread-1..........
[Finished in 1.8s

可以看到v值在被2個線程都操作了,最後線程2隻是作了一個 再拼字串的過程,因為線程1已經建立了全域變數v


#!/usr/bin/python# -*- coding: utf-8 -*-# python2.7x# author: orangelliu# date: 2014-08-20'''執行緒區域變數  初始值定義之後,線上程中可以保持隔離性為了做對比,分別和全域變數,gevent線程對比gevent 協程'''import geventfrom gevent.local import localdata = local()def bar():    print 'called from %s'%data.vdef foo(v):    data.v = v    data.v = str(data.v) + '.......'    bar()g1 = gevent.spawn(foo, '1')g2 = gevent.spawn(foo, '2')gevent.joinall([g1, g2])

called from 1.......
called from 2.......
[Finished in 0.1s]


類似線程的結果。


本文出自 “orangleliu筆記本” 部落格,請務必保留此出處http://blog.csdn.net/orangleliu/article/details/38741275
python threading模組,產生多線程之後,怎得到線程執行完成後return出的字串?

多線程/多進程都是通訊或者回調,而不是直接返回結果。這個很容易理解的,因為如果你用返回結果來給一個變數賦值,你就必須等待這個函數結束,你這個程式就阻塞了,這就失去了多線程/多進程防止阻塞的意義了。
通訊可以是事件驅動或者用安全執行緒的資料結構來傳遞資料(比如Queue,也可以是訊息佇列0mq,rabbitMQ之類),回調就是你一個程式執行完成後調用另外一個函數來處理接下來怎麼做。
 
一個對於Python多線程的新手問題

用threading模組的join函數可以檢測線程是否結束
如果只能用thread模組,可以使用標誌位,不過效率比較低,代碼風格也不好
這個相當於自旋鎖
from time import sleep,ctimeimport threaddef loop0(sign): print 'start loop 0 at:',ctime() sleep(4) print 'loop 0 done at:',ctime() sign[0]=True def loop1(sign): print 'start loop 1 at:',ctime() sleep(2) print 'loop 1 done at:',ctime() sign[1]=True def main(): print 'starting at:',ctime() sign=[False,False] thread.start_new_thread(loop0,(sign,)) thread.start_new_thread(loop1,(sign,)) while not all(sign):pass print 'all DONE at:',ctime() if __name__=='__main__': main()
 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.