python多线程基础

发布时间:2019-07-14 10:23:24编辑:auto阅读(1349)

    一、python多线程基础

        python多线程主要涉及两个类:thread和threading,后者实际是对前者的封装,由于threading提供了更完善的锁机制,运用场景更多,重点学习了这个类的使用。

    threading.Thread类的使用:

    1、在自己的线程类的__init__里调用threading.Thread.__init__(self, name = threadname),threadname为线程的名字

    2、 run(),通常需要重写,编写代码实现做需要的功能。

    3、getName(),获得线程对象名称

    4、setName(),设置线程对象名称

    5、start(),启动线程

    6、join([timeout]),等待另一线程结束后再运行。

    7、setDaemon(bool),设置子线程是否随主线程一起结束,必须在start()之前调用。默认为False。

    8、isDaemon(),判断线程是否随主线程一起结束。

    9、isAlive(),检查线程是否在运行中。

    例子如下:

    import threading  
    import time  
    
    #继承threading.Thread类
    class timer(threading.Thread): 
        def __init__(self, num, interval):  
            threading.Thread.__init__(self)  
            self.thread_num = num  
            self.interval = interval  
            self.thread_stop = False  
       
       #重新run()方法
        def run(self):
            while not self.thread_stop:  
                print 'Thread Object(%d), Time:%s\n' %(self.thread_num, time.ctime())  
                time.sleep(self.interval) 
                 
        def stop(self):  
            self.thread_stop = True  
               
    def test():  
        thread1 = timer(1, 1)  
        thread2 = timer(2, 2)  
        thread1.start()  
        thread2.start()  
        time.sleep(10)  
        thread1.stop()  
        thread2.stop()  
        return  
       
    if __name__ == '__main__':  
        test()

        通常我们通过继承threading.Thread类后重写run方法可以实现我们想做的事情,另一种实现多线程的方法是通过threading.Thread类直接生成线程,同时直接指定线程要执行的方法以及方法相应的参数。见以下例子:

    import threading
    
    def runTest(x,y):
        for i in range(x,y):
            print i
            
    t1 = threading.Thread(target=runTest,args=(15,20))
    t2 = threading.Thread(target=runTest,args=(25,35))
    
    t1.start()
    t2.start()
    t1.join()
    t2.join()


    二、线程同步

    1、简单的同步

        通过锁是实现同步最简单的方式。python的锁对象由thread.Lock类创建。基本流程如下:

    1)线程可以使用锁的acquire()方法获得锁,这样锁就进入“locked”状态;

    2)每次只有一个线程可以获得锁,如果当另一个线程试图获得这个锁的时候,就会被系统变为“blocked”状态;

    3)拥有锁的线程调用锁的release()方法来释放锁,这样锁就会进入“unlocked”状态;

    4)“blocked”状态的线程就会收到一个通知,并有权利获得锁。如果多个线程处于“blocked”状态,所有线程都会先解除“blocked”状态,然后系统选择一个线程来获得锁,其他的线程继续沉默(“blocked”)。

         这样一个锁机制存在的问题是,当一个线程获得了锁之后没有释放,又申请了同一个锁资源,此时该线程会进入blocked状态,而且形成死锁。threading.RLock锁原语解决了该问题。RLock对象允许一个线程多次对其进行acquire操作,因为在其内部通过一个counter变量维护着线程acquire的次数。而且每一次的acquire操作必须有一个release操作与之对应,在所有的release操作完成之后,别的线程才能申请该RLock对象。

    import threading  
    mylock = threading.RLock()  
    num=0  
       
    class myThread(threading.Thread):  
        def __init__(self, name):  
            threading.Thread.__init__(self)  
            self.t_name = name  
              
        def run(self):
            #num作为共享资源  
            global num  
            while True:  
                #把共享资源的处理放在acquire()和release()之间
                mylock.acquire()  
                print 'Thread(%s) locked, Number: %d\n'%(self.t_name, num)  
                if num>=4:  
                    mylock.release()  
                    print 'Thread(%s) released, Number: %d\n'%(self.t_name, num)  
                    break  
                num+=1  
                print 'Thread(%s) released, Number: %d\n'%(self.t_name, num)  
                mylock.release()  
                  
    def test():  
        t1 = myThread('t1')  
        t2 = myThread('t2')  
        t1.start()  
        t2.start()  
       
    if __name__== '__main__':  
        test()


    2、条件同步——生产者和消费者问题

            当某些条件下才会出现资源竞争的时候就会涉及条件同步。一个形象一点的例子是,伊利牛奶生产厂家可以生产好多牛奶,并将它们放在多个好又多分店进行销售,小明可以从任一间好又多分店中购买到牛奶。只有当厂家把牛奶放在某一分店里,小明才可以从这间分店中买到牛奶。看一下代码描述:

    import threading   
    import time  
      
    class Producer(threading.Thread):  
      
        def __init__(self, t_name):  
            threading.Thread.__init__(self, name=t_name)  
      
        def run(self):  
            global x  
            con.acquire() 
             
            if x > 0:  
                con.wait() 
                 
            else:  
                for i in range(5):  
                    x=x+1  
                    print "producing..." + str(x)  
                con.notify()  
     
            print x  
            con.release()  
        
    class Consumer(threading.Thread):  
      
        def __init__(self, t_name):   
            threading.Thread.__init__(self, name=t_name)  
      
        def run(self):  
            global x  
            con.acquire()  
      
            if x == 0:  
                print 'consumer wait1'  
                con.wait()
                  
            else:  
                for i in range(5):  
                    x=x-1  
                    print "consuming..." + str(x)  
      
                con.notify()  
      
            print x  
            con.release()  
      
       
      
    con = threading.Condition()    
    x=0
        
    print 'start consumer'    
    c=Consumer('consumer')
        
    print 'start producer'    
    p=Producer('producer')  
        
    p.start()    
    c.start()  
      
    p.join()    
    c.join()  
      
    print x

    据说可以用队列的FIFO特性来实现生产者和消费者问题,后续再学习。

    资源来自:http://www.cnblogs.com/tqsummer/archive/2011/01/25/1944771.html

关键字