Python*之路(三) 多线程处理

今天学习Python的多线程机制,在Python中主要使用Threading 模块,当然也有thread模块,只是这里面的功能比较单一,而Threading 模块是在thread的基础上进行的扩展,就像Python Document 上说的,这是一个Higher-level Threading interface .
 用threading模块创建线程,主要是对Thread类的实例化,根据创建实例的不同方法,主要使用下面三种:
  创建一个Thread 的实例,构造方法中传入一个函数t=threading.Thread(target=_func_name,args=(参数元组)
  创建一个Thread 的实例,构造方法中传入一个可调用的类对象定义一个类class ThreadFunc,类中必须重写__call__函数供线程调用t=threading.Thread(target=ThreadFunc实例)
  从Thread派生出一个子类,创建子类的实例class MyThread(threading.Thread)重写threading.Thread中的run函数供线程执行。
所有上述线程创建后,都采用线程实例的start()的方法启动,join()方法加自旋锁。
关于自旋锁,多个线程运行时,怎样确保所有重要线程都已经结束呢?在threading模块中,每个Thread类都有一个join函数,其实就是一个等待此线程锁释放的无限循环(也称为自旋锁)。当一个线程实例启动时,显式调用join()会使主线程*等待该线程的自旋锁释放。这种情况在顺序过程的任务流程序中比较常见。
学到这里,我想,不妨做一个通用的模块,对任意过程实现线程同步处理。比如一个下载过程,只需要传入URL就可以了,主线程不必等待下载完成才执行其他任务,对于这样一个特殊的过程函数,我们可以使用函数修饰功能。
 class wraps:
 #=======================================
 # only for process without result,
 # and main do not wait for it finished
 #=======================================     
    @staticmethod
    def thread(f):
        def wrappFunc(*args,**kargs):
            try:
                _thread=BaseThread(f,args,f.__name__)
                _thread.start()
            except Exception,e:
                print e
        return wrappFunc 
 其中BaseThread继承了threading.Thread类,负责线程对象的创建工作。
 class BaseThread(Thread):
    def __init__(self,func,args,name=''):
        threading.Thread.__init__(self)
        self.name=name
        self.args=args
        self.func=func
        self.res=None
    def getResult(self):
        return self.res
    def run(self):
        print 'starting',self.name,'at:',ctime()
        self.res=self.func(*self.args)
        print 'finished',self.name,'at:',ctime()
 把这些类放在一个单独的模块中basethread中,看看如何在我们平常的程序中调用:
 From basethread import wraps
 @wraps.thread
def test(sec):
    for i in range(sec):
        sleep(1)
  
test(4)
test(3)
test(1)
test(2)
结果没上传上来 ,大意就是都是同时开始,按1,2,3,4秒结束,共耗时4秒。
还有一个更强大的模块Mutiprocessing ----- process – base threading interface,以后再讨论。
上一篇:Linux tar指令


下一篇:Nutch 1.0 完全配置笔记