8-3 如何线程间事件通知

一、tar包打包

import tarfile
import os

def FunTarFile(tfname):
    tf = tarfile.open(tfname,'w:gz') #open打开一个tar包,‘w’打开模式为写 ‘:gz’压缩模式gzip

    for fname in os.listdir('.'):     #遍历当前目录的文件
        if fname.endswith('.docx'):
            tf.add(fname)             #将此文件加入tar包
            os.remove(fname)          #移除此文件

    tf.close()
    print (tf.members)                #打印tar包成员信息
    if not tf.members:              #判断tar包是否为空
        os.remove(tfname)           #如果tar包为空,删除此tar包

FunTarFile('DocxTar.tgz')

输出结果:

[<TarInfo '8-1 \xc8\xe7\xba\xce\xca\xb9\xd3\xc3\xb6\xe0\xcf\xdf\xb3\xcc - \xb8\xb1\xb1\xbe.docx' at 0x27d0330>, <TarInfo '8-2 \xc8\xe7\xba\xce\xcf\xdf\xb3\xcc\xbc\xe4\xcd\xa8\xd0\xc5 - \xb8\xb1\xb1\xbe.docx' at 0x27d0370>, <TarInfo '8-3 \xc8\xe7\xba\xce\xcf\xdf\xb3\xcc\xbc\xe4\xca\xc2\xbc\xfe\xcd\xa8\xd6\xaa - \xb8\xb1\xb1\xbe.docx' at 0x2602d30>]

二、事件通知使用方法:

>>> from threading import Event,Thread
>>> 
>>> def f(e):
    print('f 0')
    e.wait()            #事件等待,阻塞
    print('f 1')

    
>>> e = Event()
>>> t = Thread(target=f, args=(e,))  #创建子线程,运行f函数
>>> t.start()         #子线程运行
f 0                 #子线程阻塞到事件等待中
>>> 
e.set()               #主线程里 事件发送
f 1                 #子线程继续执行
>>> 

此时再调用 wait()阻塞时,就不再起作用了,需要先调用e.clear()清除才能再使用wait()阻塞

 

# -*- coding: cp936 -*-

from threading import Thread,Event
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,tEvent,cEvent):
        #Thread.__init__(self)
        super(ConvelThread,self).__init__()
        self.queue = queue
        self.tEvent = tEvent
        self.cEvent = cEvent
        self.count = 0

    def convel(self,sid,data):
        print("Convel  (%d)-(%d)" %(sid ,data))

    def run(self):
        while(True):
            sid, data = self.queue.get() #元组解包的形式得到数据
            if(sid == -1):
                if self.count != 0:      #当退出时判断是否还需要打包的,
                    self.tEvent.set()   #如需要发送打包事件
                    self.cEvent.wait()  #并等待打包完再退出。
                break
            if(data):
                self.convel(sid,data)
                self.count += 1
                if self.count == 5:
                    self.tEvent.set()   #发送打包事件
                    self.cEvent.wait()  #等待转换事件
                    self.tEvent.clear() #清空打包事件
                    self.count = 0
                    

"""
打包线程,等到转换线程通知后,开始打包,打包完成后通知转换线程继续转换,此线程暂停打包
"""
class TarThread(Thread):
    def __init__(self,tEvent,cEvent):
        #Thread.__init__(self)
        super(TarThread,self).__init__()
        self.count = 0
        self.tEvent = tEvent
        self.cEvent = cEvent
        self.setDaemon(True)                #设置守护线程,当其他所有线程结束了,此线程也结束

    def FunTar(self,count):
        print ('Tar count - %d' %count)

    def run(self):
        while True:
            self.tEvent.wait()          #等特打包事件通知 
            self.count += 1
            self.FunTar(self.count)
            self.tEvent.clear()         #清空打包事件
            self.cEvent.set()           #发送转换事件
            

if __name__ == '__main__':
    q = Queue()
    tEvent = Event()
    cEvent = Event()

    dThreads = [DownThread(i,q) for i in xrange(1,13)]

    cThread = ConvelThread(q,tEvent,cEvent)
    tThread = TarThread(tEvent,cEvent)

    for t in dThreads:
        t.start()
        
    cThread.start()
    tThread.start()
    for t in dThreads:
        t.join()
        

    q.put((-1,None))

    cThread.join()
   # tThread.join()     #有此代码时,不打印下面的,因为主线程等待转换线程退出,转换线程是守护线程,需要所有线程都退出后,才能退出

print('MainThread')

 

输出结果:

Download (1)...Download (4)...Download (2)...Download (5)...Download (3)...Download (6)...Download (7)...Download (8)...Download (9)...Download (10)...Download (11)...Download (12)...

Convel  (1)-(101)
Convel  (4)-(104)
Convel  (2)-(102)
Convel  (5)-(105)
Convel  (3)-(103)
Tar count - 1
Convel  (6)-(106)
Convel  (7)-(107)
Convel  (8)-(108)
Convel  (9)-(109)
Convel  (10)-(110)
Tar count - 2Convel  (11)-(111)

Convel  (12)-(112)
Tar count - 3MainThread

 

 

 

posted on 2018-05-08 16:59  石中玉smulngy  阅读(176)  评论(0编辑  收藏  举报

导航