Python中的多线程threading和线程间消息队列queue学习笔记

    python中实现多线程可以通过threading类。线程间同步则可以用queue类。至于python的进程间通信,暂时没有发现有类似linux ipc的模块可供使用,但是可以通过unix域套接字实现进程间通信。

1、用threading模块实现多线程

    可以通过派生threading.Thread类来实现一个可独立控制的线程实例。用户需要(也只能)重写Thread类的__init__和run函数来实现自己的线程。线程类实例化后可以通过使用start函数使线程运行,该函数会在新开启的线程中调用run函数。这里需要注意的是,该类中只有run函数是出在独立的线程中运行的,其他控制函数都是处在调用者线程中执行的。其他线程可以通过调用Thread实例的join函数来阻塞自己等待线程运行结束。Thread类中name属性用来存放线程的名字。在python中主线程是一个名为“ main thread”的Thread实例。
1.1、Thread类中的函数
    start():启动线程 。只能调用一次,否则会报错。该函数启动一个单独的线程运行run函数。
    run():通过重写这个函数来实现用户函数在线程中的运行。也可以在类实例化的时候直接指定运行函数,那样的话可以不用重写这个函数,
    join(timeout=None):调用这个函数的线程收到阻塞直到线程实例退出。timeout,一个浮点数,可以指定超时时间,单位秒。
    name存放线程的名字。可以更改,默认为Thread-n的格式。
   ident:存放线程标识,一个整数。在线程结束后依然存在(直到线程资源被回收)
   is_alive()判断线程是否存活。返回True或者False。调用模块函数 enumerate()可以得到所以存活的线程。
  daemon指定线程是否为守护线程

1.2、线程实例

    
    
  1. import threading
  2. import Queue
  3. import time
  4. class mn_access(threading.Thread):
  5. def __init__(self,interval):
  6. threading.Thread.__init__(self)
  7. self.interval=interval
  8. self.thread_stop= False
  9. def run(self): #这个函数中存放用户自己的功能代码
  10. i= 1;
  11. while not self.thread_stop:
  12. print( "thread%d %s: i am alive hehe %d" %(self.ident,self.name,i))
  13. time.sleep(self.interval)
  14. i=i+ 1
  15. def stop(self):
  16. self.thread_stop = True
  17. if __name__ == "__main__":
  18. mn=mn_access( 1)
  19. mn.start() #线程开始
  20. time.sleep( 5)
  21. mn.stop()
以上代码实现一个简单的线程实例,这段代码会生成一个线程并且周期性打印以证明自己存活。程序运行后打印:
thread140109270083328 Thread-1: i am alive hehe 1
thread140109270083328 Thread-1: i am alive hehe 2
thread140109270083328 Thread-1: i am alive hehe 3
thread140109270083328 Thread-1: i am alive hehe 4
thread140109270083328 Thread-1: i am alive hehe 5

2、Queue模块:线程间的消息队列


    queue模块用来实现消息队列功能,可以实现线程间安全的消息交换。各个线程可以通过调用消息队列实例对消息队列进行操纵。
2.1、queue对象
    queue对象实现一个fifo队列(其他的还有lifo、priority队列,这里不再介绍)。queue只有qsize一个构造参数,用来指定队列容量,指定为0的时候代表容量无限。主要有以下成员函数:
     Queue. qsize ( ):返回消息队列的当前空间。返回的值不一定可靠。
     Queue. empty ( ):判断消息队列是否为空,返回True或False。同样不可靠。
     Queue. full ( ):类似上边,判断消息队列是否满
     Queue. put ( item block=True timeout=None ):往消息队列中存放消息。block可以控制是否阻塞,timeout指定阻塞时候的等待时间。如果不阻塞或者超市,会引起一个full exception。
     Queue. put_nowait ( item ):相当于 put(item, False) .
     Queue. get ( block=True timeout=None ):获取一个消息,其他同put。
    以下两个函数用来判断消息对应的任务是否完成。
     Queue. task_done ( ):接受消息的线程通过调用这个函数来说明消息对应的任务已完成。
     Queue. join ( ):调用线程阻塞直到所有消息对应的任务已经完成。
    消息队列实例中维护的有待完成任务变量。每接收到一个消息该值自增一次。每调用一次.task_done()可以使该值减1,当待完成任务值为0的时候,join函数才会返回。
2.2、 queue例子:

     
     
  1. import threading
  2. import Queue
  3. import time
  4. class worker(threading.Thread):
  5. def __init__(self,queue):
  6. threading.Thread.__init__(self)
  7. self.queue=queue
  8. self.thread_stop= False
  9. def run(self):
  10. while not self.thread_stop:
  11. print( "thread%d %s: waiting for tast" %(self.ident,self.name))
  12. try:
  13. task=q.get(block= True, timeout= 20) #接收消息
  14. except Queue.Empty:
  15. print( "Nothing to do!i will go home!")
  16. self.thread_stop= True
  17. break
  18. print( "task recv:%s ,task No:%d" % (task[ 0],task[ 1]))
  19. print( "i am working")
  20. time.sleep( 3)
  21. print( "work finished!")
  22. q.task_done() #完成一个任务
  23. res=q.qsize() #判断消息队列大小
  24. if res> 0:
  25. print( "fuck!There are still %d tasks to do" % (res))
  26. def stop(self):
  27. self.thread_stop = True
  28. if __name__ == "__main__":
  29. q=Queue.Queue( 3)
  30. worker=worker(q)
  31. worker.start()
  32. q.put([ "produce one cup!", 1], block= True, timeout= None) #产生任务消息
  33. q.put([ "produce one desk!", 2], block= True, timeout= None)
  34. q.put([ "produce one apple!", 3], block= True, timeout= None)
  35. q.put([ "produce one banana!", 4], block= True, timeout= None)
  36. q.put([ "produce one bag!", 5], block= True, timeout= None)
  37. print( "***************leader:wait for finish!")
  38. q.join() #等待所有任务完成
  39. print( "***************leader:all task finished!")

    以上程序实现一个简单的消费者-生产者模型。主线程通过消息队列向worker线程分配任务,worker线程完成任务后调用
task_done()使得待完成任务数减一。主线程通过join等待生产者完成任务,生产者完成所有任务后主线程退出。代码输出:
thread139958685849344 Thread-1: waiting for tast 1
task recv:produce one cup! ,task No:1
i am working
work finished!
fuck!There are still 3 tasks to do
thread139958685849344 Thread-1: waiting for tast 1
task recv:produce one desk! ,task No:2
i am workingleader:wait for finish!
work finished!
fuck!There are still 3 tasks to do
thread139958685849344 Thread-1: waiting for tast 1
task recv:produce one apple! ,task No:3
i am working
work finished!
fuck!There are still 2 tasks to do
thread139958685849344 Thread-1: waiting for tast 1
task recv:produce one banana! ,task No:4
i am working
work finished!
fuck!There are still 1 tasks to do
thread139958685849344 Thread-1: waiting for tast 1
task recv:produce one bag! ,task No:5
i am working
work finished!
thread139958685849344 Thread-1: waiting for tast 1
 ***************leader:all task finished!
Nothing to do!i will go home!

猜你喜欢

转载自blog.csdn.net/qq_31511955/article/details/88170879
今日推荐