第18章 多线程编程(3)

18.5 threading模块

Threading模块支持守护线程,它们是这样工作的:守护线程一般是一个等待客户请求服务器,如果客户提出请求,它就在那等着。如果你设定一个线程为守护线程,就表示你在说这个线程是不重要的,在进程退出的时候,不用等待这个线程退出。

如果你的主线程要退出的时候,不用等待那些子线程完成,那就设定这些线程的daemon属性。即,在线程开始(调用thread.start())之前,调用setDaemon()函数设定线程的daemon标志(thread.setDaemon(True))就表示这个线程"不重要".

如果你想要等待子线程完成再退出,那就什么都不用做,或者显式地调用thread.setDaemon(False)以保证其daeMon标志为False。你可以调用thread.isDaemon()函数来判断其daemon标志的值。新的子线程会继承其父线程的daemon标志。整个Python会在所有的非守护线程退出后才会结束,即进程中没有非守护线程存在的时候才结束。

18.5.1 thread类

import threading
from time import ctime, sleep

loops = [4, 2]

def loop(nloop, nsec):
    print 'start loop ', nloop, ' at: ', ctime()
    sleep(nsec)
    print 'loop ', nloop, ' done at: ', ctime()

def main():
    print 'starting at: ', ctime()
    threads = []
    nloops = range(len(loops))
    
    for i in nloops:
        t = threading.Thread(target = loop, args = (i, loops[i]))
        threads.append(t)
    
    for i in nloops:
        threads[i].start()
    
    for i in nloops:
        threads[i].join()
        
    print 'all DONE at: ', ctime()

main()
实例化每个Thread对象的时候,我们把函数(target)和参数(args)传进去,得到返回的Thread实例。实例化一个Thread(调用Thread())与调用thread.start_new_thread()之间最大的区别就是,先的线程不会立即开始。当你创建线程对象,但不想马上开始运行线程的时候,这是一个非常有用的同步特性。

join()会等到线程结束,或者在给了timeout参数的时候,等到超时为止。

join()的另一个比较重要的方面是它可以完全不用调用。一旦线程启动之后,就会一直运行,知道线程的函数结束,退出为止。如果你的主线程除了等待线程结束外,还有其他的事情要做,那就不用调用join(),只有你要等待线程结束的时候才要调用join()。

import threading
from time import ctime, sleep

loops = [4, 2]

class ThreadFunc(object):
    def __init__(self, func, args, name=''):
        self.func = func
        self.args = args
        self.name = name
    
    def __call__(self):
        apply(self.func, self.args)
    
def loop(nloop, nsec):
    print 'start loop ', nloop, ' at: ', ctime()
    sleep(nsec)
    print 'loop ', nloop, ' done at: ', ctime()

def main():
    print 'starting at: ', ctime()
    threads = []
    nloops = range(len(loops))
    
    for i in nloops:
        t = threading.Thread(target = ThreadFunc(loop, (i, loops[i]), loop.__name__))
        threads.append(t)
    
    for i in nloops:
        threads[i].start()
    
    for i in nloops:
        threads[i].join()
        
    print 'all DONE at: ', ctime()

main()
创建新线程的时候,Thread对象会调用我们的ThreadFunc对象,这时会用到一个特殊函数__call__()。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值