使用Queue对象来控制多线程Threading的同步问题

#coding: utf-8


import threading
import time
import Queue



u'''使用Queue对象来控制多线程的同步问题。典型的例子:生产者、消费者模型。线程需要同步,是因为多个线程对某个共享数据进行修改时,有可能出现意想不到的结果,要保证数据的准确性。
以下例子,每个生产者Producer线程将数据(线程名)依次存入队列queque_1,而每个消费者Consumer线程则依次从队列queue_1中取出数据(线程名).
逻辑:
1.先分别定义:生产者线程和消费者线程。生产者线程的功能是,将线程名放入队列queue_1并且打印相关信息(见run()函数)。而消费者线程的功能是,从队列queue_1中得到数据即生产者Producer的线程名,并打印相关信息。
2.通过for循环,生成10个生产者线程 和 生成10个消费者线程,并将他们分别放入plist、clist
3.通过for循环,执行相关的线程。
总结:
a).就是将要处理的数据按顺序放入队列queue_1,然后按顺序从队列中取出数据,来保证多个线程对共享数据的同步操作。
b).通过继承threading模块中的Thread创建类,重载run()方法后,可以通过start()方法来创建线程!run()是threading.Thread中的自带方法,可通过start来启动线程.
'''

# 1.先分别定义:生产者线程和消费者线程。生产者线程的功能是,将线程名放入队列queue_1并且打印相关信息(见run()函数)。而消费者线程的功能是,从队列queue_1中得到数据即生产者Producer的线程名,并打印相关信息。
class Producer(threading.Thread): # 创建生产者线程类,所需参数见__init__()(因为,在调用类的时候,会首先自动调用__init__()函数。),线程类实际运行的是线程类中自带的run()方法。

 """docstring for ClassName"""
 def __init__(self, threadname):
  #threading.Thread.__init__(self, name = threadname)  # 调用父类的初始方法(也可以如下方式); 线程名变量 threadname  ; 系统默认的线程名格式为Thread-1, Thread-2 ...
  threading.Thread.__init__(self)  # 调用父类的初始方法(必须的,因为Producer类是继承了threading.Thread的);
  self.name = threadname
 def run(self):   #重写run()方法, 线程类实际运行的是线程类中自带的run()方法,之后就可以通过start()方法来创建线程了。若将run名字改成其它的,如run_2(),则有问题,不执行。
  global queue_1
  queue_1.put(self.getName())  #调用队列put方法,将线程名(threadname = self.getName())添加到队列queue_1中。queue_1 = Queue.Queue()
  print self.getName(), 'put ', self.getName(), ' to queue_1'
class Consumer(threading.Thread):
 """docstring for ClassName"""
 def __init__(self, threadname):
  threading.Thread.__init__(self, name = threadname)
 def run(self):
  global queue_1
  print self.getName(), 'get ', queue_1.get(), ' from queue_1'  #调用队列get方法,获取队列queue_1中的内容。
queue_1 = Queue.Queue()  #生成队列对象。

# 2.生成10个生产者线程 和 生成10个消费者线程,并将他们分别放入plist、clist
plist = []   #生产者对象列表
clist = []   #消费者对象列表
for i in range(10):
 p = Producer('Producer' + str(i))   # 'Producer' + str(i) 是 Producer 类的线程名 threadname
 #p = Producer()  # 尝试: 这样没给参数(实际上是给了一个self参数),会报错,TypeError: __init__() takes exactly 2 arguments (1 given),另一种解决办法可以将Producer类中__init__()注释掉。
 plist.append(p)   #生成10个生产者线程的列表,线程名为'Producer' + str(i)
for i  in range(10):
    c = Consumer('Consumer' + str(i))   # 'Consumer' + str(i) 是 Consumer 类的线程名 threadname
    clist.append(c)   #生成10个消费者线程的列表,线程名为'Consumer' + str(i)

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

转载于:https://my.oschina.net/u/1583171/blog/270652

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值