Chinaunix首页 | 论坛 | 博客
  • 博客访问: 123917
  • 博文数量: 83
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 585
  • 用 户 组: 普通用户
  • 注册时间: 2014-05-13 10:26
个人简介

- 毅力与勇气是事业的双飞翼; - 在尝试中成长,在失败中奋起。 - 概览 -> 细读 -> 概览 - 书不在多,在于精。

文章分类

全部博文(83)

文章存档

2016年(2)

2015年(6)

2014年(75)

我的朋友

分类: LINUX

2014-05-29 15:07:46


点击(此处)折叠或打开

  1. #coding: utf-8

  2. import threading
  3. import time
  4. import Queue

  5. u'''使用Queue对象来控制多线程的同步问题。典型的例子:生产者、消费者模型。线程需要同步,是因为多个线程对某个共享数据进行修改时,有可能出现意想不到的结果,要保证数据的准确性。

  6. 以下例子,每个生产者Producer线程将数据(线程名)依次存入队列queque_1,而每个消费者Consumer线程则依次从队列queue_1中取出数据(线程名).
  7. 逻辑:
  8. 1.先分别定义:生产者线程和消费者线程。生产者线程的功能是,将线程名放入队列queue_1并且打印相关信息(见run()函数)。而消费者线程的功能是,从队列queue_1中得到数据即生产者Producer的线程名,并打印相关信息。

  9. 2.通过for循环,生成10个生产者线程 和 生成10个消费者线程,并将他们分别放入plist、clist

  10. 3.通过for循环,执行相关的线程。

  11. 总结:
  12. a).就是将要处理的数据按顺序放入队列queue_1,然后按顺序从队列中取出数据,来保证多个线程对共享数据的同步操作。
  13. b).通过继承threading模块中的Thread创建类,重载run()方法后,可以通过start()方法来创建线程!run()是threading.Thread中的自带方法,可通过start来启动线程.
  14. '''

  15. # 1.先分别定义:生产者线程和消费者线程。生产者线程的功能是,将线程名放入队列queue_1并且打印相关信息(见run()函数)。而消费者线程的功能是,从队列queue_1中得到数据即生产者Producer的线程名,并打印相关信息。

  16. class Producer(threading.Thread): # 创建生产者线程类,所需参数见__init__()(因为,在调用类的时候,会首先自动调用__init__()函数。),线程类实际运行的是线程类中自带的run()方法。
  17.     """docstring for ClassName"""
  18.     def __init__(self, threadname):
  19.         #threading.Thread.__init__(self, name = threadname) # 调用父类的初始方法(也可以如下方式); 线程名变量 threadname ; 系统默认的线程名格式为Thread-1, Thread-2 ...
  20.         threading.Thread.__init__(self) # 调用父类的初始方法(必须的,因为Producer类是继承了threading.Thread的);
  21.         self.name = threadname

  22.     def run(self): #重写run()方法, 线程类实际运行的是线程类中自带的run()方法,之后就可以通过start()方法来创建线程了。若将run名字改成其它的,如run_2(),则有问题,不执行。
  23.         global queue_1
  24.         queue_1.put(self.getName()) #调用队列put方法,将线程名(threadname = self.getName())添加到队列queue_1中。queue_1 = Queue.Queue()
  25.         print self.getName(), 'put ', self.getName(), ' to queue_1'

  26. class Consumer(threading.Thread):
  27.     """docstring for ClassName"""
  28.     def __init__(self, threadname):
  29.         threading.Thread.__init__(self, name = threadname)

  30.     def run(self):
  31.         global queue_1
  32.         print self.getName(), 'get ', queue_1.get(), ' from queue_1' #调用队列get方法,获取队列queue_1中的内容。

  33. queue_1 = Queue.Queue() #生成队列对象。

  34. # 2.生成10个生产者线程 和 生成10个消费者线程,并将他们分别放入plist、clist
  35. plist = [] #生产者对象列表
  36. clist = [] #消费者对象列表

  37. for i in range(10):
  38.     p = Producer('Producer' + str(i)) # 'Producer' + str(i) 是 Producer 类的线程名 threadname
  39.     #p = Producer() # 尝试: 这样没给参数(实际上是给了一个self参数),会报错,TypeError: __init__() takes exactly 2 arguments (1 given),另一种解决办法可以将Producer类中__init__()注释掉。
  40.     plist.append(p) #生成10个生产者线程的列表,线程名为'Producer' + str(i)

  41. for i in range(10):
  42.     c = Consumer('Consumer' + str(i)) # 'Consumer' + str(i) 是 Consumer 类的线程名 threadname
  43.     clist.append(c) #生成10个消费者线程的列表,线程名为'Consumer' + str(i)

  44. # 3.执行相关的线程。
  45. for i in plist:
  46.     i.start() #执行生产者线程
  47.     i.join() #join()保证了i线程执行完之后才进行下一个任务。

  48. for i in clist:
  49.     i.start() #执行消费者线程
  50.     i.join()

阅读(505) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~