[Python]threading local 線程局部變量小測試

概念     

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

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

全局變量

 

線程局部變量

 

 

對比:

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

#!/usr/bin/python
# -*- coding: utf-8 -*-
# python2.7x
# author: orangelliu
# date: 2014-08-20

'''
線程本地變量  初始值定義之後,在線程中可以保持隔離性
爲了做對比,分別和全局變量,gevent線程對比

線程局部變量
'''

from time import sleep
from random import random
from threading import Thread, local

data = local()

def bar():
    print 'called from %s'%data.v

def 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 sleep
from random import random
from threading import Thread, local

#如果使用全局變量呢
def bar1():
    global v
    print 'calledddddd from %s'%v

def 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 gevent
from gevent.local import local

data = local()

def bar():
    print 'called from %s'%data.v

def 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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章