-
#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()
阅读(534) | 评论(0) | 转发(0) |