当我们使用线程的时候,能使用线程的局部变量,就尽量不要用全局变量,因为使用全局变量涉及同步的问题(参见我的上一篇博客Python学习总结笔记(3)–多线程与线程同步 )。
使用局部变量的时候,需要传递参数,比如有这样一个例子,程序需要处理客户申请,每来一个客户,就新开一个线程进行处理,而客户有姓名、年龄、性别等属性(参数),如果都需要传递参数的话很繁琐。Python提供了threading.local模块,方便我们实现线程局部变量的传递。直接看下面的例子:
# /usr/bin/env python
# coding:utf-8
__author__ = 'kikay'
import threading
# Threading.local对象
ThreadLocalHelper = threading.local()
lock = threading.RLock()
class MyTheadEx(threading.Thread):
def __init__(self, threadName, name, age, sex):
super(MyTheadEx, self).__init__(name=threadName)
self.__name = name
self.__age = age
self.__sex = sex
def run(self):
global ThreadLocalHelper
ThreadLocalHelper.ThreadName = self.name
ThreadLocalHelper.Name = self.__name
ThreadLocalHelper.Age = self.__age
ThreadLocalHelper.Sex = self.__sex
MyTheadEx.ThreadPoc()
# 线程处理函数
@staticmethod
def ThreadPoc():
lock.acquire()
try:
print 'Thread={id}'.format(id=ThreadLocalHelper.ThreadName)
print 'Name={name}'.format(name=ThreadLocalHelper.Name)
print 'Age={age}'.format(age=ThreadLocalHelper.Age)
print 'Sex={sex}'.format(sex=ThreadLocalHelper.Sex)
print '----------'
finally:
lock.release()
if __name__ == '__main__':
Tom = {'Name': 'tom', 'Age': 20, 'Sex': 'man'}
xiaohua = {'Name': 'xiaohua', 'Age': 18, 'Sex': 'woman'}
Andy = {'Name': 'Andy', 'Age': 40, 'Sex': 'man'}
T = (Tom, xiaohua, Andy)
threads = []
for i in range(len(T)):
t = MyTheadEx(threadName='id_{0}'.format(i), name=T[i]['Name'], age=T[i]['Age'], sex=T[i]['Sex'])
threads.append(t)
for i in range(len(threads)):
threads[i].start()
for i in range(len(threads)):
threads[i].join()
print 'All Done!!!'
运行结果:
Thread=id_0
Name=tom
Age=20
Sex=man
----------
Thread=id_1
Name=xiaohua
Age=18
Sex=woman
----------
Thread=id_2
Name=Andy
Age=40
Sex=man
----------
All Done!!!
可见,每个线程都可以对threading.local对象进行读写,且互相不干扰。合理使用threading.local可以极大简化代码逻辑,同时保证各个子线程的数据安全。Threading.local最大的用处就是HTTP请求时绑定用户的信息,这样每个用户线程可以非常方便访问各自的资源而互不干扰。