一、题目:
熟悉线程相关知识后,利用Lock和RLock实现线程间的简单同步,使得10个线程对同一共享变量进行递增操作,使用加锁机制保证变量结果的正确。
二、主要难点
1. 一般而言创建自己的线程类,可以重写threading.Thread类的方法
threading.Thread类的使用:
I,在自己的线程类的__init__里调用threading.Thread.__init__(self, name = threadname),Threadname为线程的名字
II, run(),通常需要重写,编写代码实现做需要的功能。
III,getName(),获得线程对象名称
IV,setName(),设置线程对象名称
V,start(),启动线程
VI,jion([timeout]),等待另一线程结束后再运行。
VII,setDaemon(bool),设置子线程是否随主线程一起结束,必须在start()之前调用。默认为False。
VIII,isDaemon(),判断线程是否随主线程一起结束。 VIIII,isAlive(),检查线程是否在运行中。
此外threading模块本身也提供了很多方法和其他的类,可以帮助我们更好的使用和管理线程。可以参看http://www.python.org/doc/2.5.2/lib/module-threading.html。
2.线程同步方法
线程同步可以使用RLock锁和Event(信号量)两种种方法实现。 RLock的核心思想是在访问时候对变量加锁 Event的核心思想是在把欲访问的全局变量放入临界区,标志被设置则不能访问,阻塞进程,若标志被清除则可以访问,同时解放那些阻塞的进程。
三、实现代码
用RLock实现:
#-*- coding:utf-8 -*- #FileName:thread.py #Author:Xue Weiwei@USTC #Last-Modify:2012-5-16 '''使用线程锁机制使多个线程对一个变量递增 @note:python的多线程使用,Rlock线程锁的使用''' from threading import Thread from threading import RLock import time class addthread(Thread): ''' 自定义线程类,方便使用,实现多个线程访问一个变量的作用 ''' def __init__(self,threadname): Thread.__init__(self,name=threadname) def run(self): ''' run函数中写下具体线程实现功能,这里是实现全局变量递增的操作 @note: 用lock ''' global SHARE_VAL lock.acquire() SHARE_VAL+=1 print SHARE_VAL lock.release() return 0 if __name__=='__main__': SHARE_VAL=0 lock=RLock() threadlist=[] begin=time.time() for i in range(10): temp = addthread("Thread%d"%i) threadlist.append(temp) for eachthread in threadlist: eachthread.start() for eachthread in threadlist: #所有线程退出,否则程序不会结束 eachthread.join() print "use %s s"%(time.time()-begin)
用Event实现
(因为原理大体相同,就没有自己写,引用自http://wiki.woodpecker.org.cn/moin/ObpLovelyPython/LpyAttAnswerCdays)
#coding:utf-8 '''cdays+3-exercise-3.py 使用Thread和Event实现简单的线程间通信 @see: Event(http://docs.python.org/lib/event-objects.html) @author: U{shengyan<mailto:shengyan1985@gmail.com>} @version:$Id$ ''' from threading import Thread from threading import Event import time class myThread(Thread): '''myThread 自定义线程 ''' def __init__(self, threadname): Thread.__init__(self, name = threadname) def run(self): global event global share_var if event.isSet(): #判断event的信号标志 event.clear() #若设置了,则清除 event.wait() #并调用wait方法 #time.sleep(2) share_var += 1 #修改共享变量 print '%s ==> %d' % (self.getName(), share_var) else: share_var += 1 #未设置,则直接修改 print '%s ==> %d' % (self.getName(), share_var) #time.sleep(1) event.set() #设置信号标志 if __name__ == "__main__": share_var = 0 event = Event() #创建Event对象 event.set() #设置内部信号标志为真 threadlist = [] for i in range(10): #创建10个线程 my = myThread('Thread%d' % i) threadlist.append(my) for i in threadlist: #开启10个线程 i.start() print "%s start\n"%i.getName()
四、参考资料
1.http://www.cnblogs.com/tqsummer/archive/2011/01/25/1944771.html
2.http://wiki.woodpecker.org.cn/moin/ObpLovelyPython/LpyAttAnswerCdays