8-2 如何线程间通信
IO操作用多线程操作,而CPU密集型操作因为有全局解释器锁GIL,所以只使用一个线程,现在下载多线程,转换一个线程,典型的供销模式关系。下载线程完成后通知转换线程进行转换。
线程间通讯本例中采用队列的方式。
from collections import deque 中的deque是双端循环队列,采用这种队列的方式在线程间操作时需要注意加锁。
使用Queue.Queue 是一个线程安全的队列,内部自动实现了加锁解锁的操作。
# -*- coding: cp936 -*- from threading import Thread from Queue import Queue from time import sleep class DownThread(Thread): def __init__(self,sid,queue): #Thread.__init__(self) super(DownThread,self).__init__() self.sid = sid self.queue = queue def downLoad(self,sid): print("Download (%d)..." %sid) sleep(2) def run(self): self.downLoad(self.sid) data = self.sid+100 self.queue.put((self.sid,data)) class ConvelThread(Thread): def __init__(self,queue): #Thread.__init__(self) super(ConvelThread,self).__init__() self.queue = queue def convel(self,sid,data): print("Convel (%d)-(%d)" %(sid ,data)) def run(self): while(True): sid, data = self.queue.get() #元组解包的形式得到数据 if(sid == -1): #当从队列读出-1时 线程退出结束 break if(data): self.convel(sid,data) q = Queue() dThreads = [DownThread(i,q) for i in xrange(1,11)] cThread = ConvelThread(q) for t in dThreads: t.start() cThread.start() for t in dThreads: t.join() q.put((-1,None)) #往队列中写入-1使 转换线程结束 cThread.join() print('MainThread')
结果输出:
Download (1)...Download (5)...Download (2)...Download (3)...Download (6)...Download (4)...Download (7)...Download (8)...Download (9)...Download (10)...
Convel (1)-(101)
Convel (5)-(105)
Convel (2)-(102)
Convel (3)-(103)
Convel (6)-(106)
Convel (7)-(107)
Convel (4)-(104)
Convel (8)-(108)
Convel (9)-(109)
Convel (10)-(110)
MainThread
posted on 2018-05-08 16:55 石中玉smulngy 阅读(154) 评论(0) 编辑 收藏 举报