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编辑  收藏  举报

导航