Python多线程学习 setDae
(2)setDaemon方法:
# -*- coding: utf-8 -*-
import threading
import time
class myThread(threading.Thread):
def __init__(self, threadname):
threading.Thread.__init__(self, name=threadname)
def run(self):
time.sleep(5)
print '%s is running·······done'%self.getName()
t=myThread('son thread')
#t.setDaemon(True)
t.start()
if t.isDaemon():
print "the father thread and the son thread are done"
else:
print "the father thread is waiting the son thread····"
这段代码的运行流程是:主线程打印完最后一句话后,等待son thread 运行完,然后程序才结束,所以输出结果为:
- the father thread is waitting the son thread····
- son thread is running·······done
<span style="font-size:24px;">the father thread is waitting the son thread····
son thread is running·······done</span>
如果启用t.setDaemon(True) ,这段代码的运行流程是:当主线程打印完最后一句话后,不管 son thread 是否运行完,程序立即结束,所以输出结果为:
- the father thread and the son thread are done
线程的合并
python的Thread类中还提供了join()方法,使得一个线程可以等待另一个线程执行结束后再继续运行。这个方法还可以设定一个timeout参数,避免无休止的等待。因为两个线程顺序完成,看起来象一个线程,所以称为线程的合并。一个例子:
- import threading
- import random
- import time
- class MyThread(threading.Thread):
- def run(self):
- wait_time=random.randrange(1,10)
- print "%s will wait %d seconds" % (self.name, wait_time)
- time.sleep(wait_time)
- print "%s finished!" % self.name
- if __name__=="__main__":
- threads = []
- for i in range(5):
- t = MyThread()
- t.start()
- threads.append(t)
- print 'main thread is waitting for exit...'
- for t in threads:
- t.join(1)
-
- print 'main thread finished!'
执行结果:
- Thread-1 will wait 3 secondsThread-2 will wait 4 seconds
- Thread-3 will wait 1 seconds
- Thread-4 will wait 5 seconds
- Thread-5 will wait 3 seconds
- main thread is waitting for exit...
- Thread-3 finished!
- Thread-1 finished!
- Thread-5 finished!
- main thread finished!
- Thread-2 finished!
- Thread-4 finished!
对于sleep时间过长的线程(这里是2和4),将不被等待。
注意:
Thread.join([timeout])Wait until the thread terminates. This blocks the calling thread until the thread whose join() method is called terminates – either nORMally or through an unhandled exception – or until the optional timeout
occurs.也就是通过传给join一个参数来设置超时,也就是超过指定时间join就不在阻塞进程。而在实际应用测试的时候发现并不是所有的线程在超时时间内都结束的,而是顺序执行检验是否在time_out时间内超时,例如,超时时间设置成2s,前面一个线程在没有完成的情况下,后面线程执行join会从上一个线程结束时间起再设置2s的超时。
根据这段解释,来分析一下程序的运行:
main thread先对Thread-1执行join操作,有1秒的timeout。
当过去1秒之后,main thread发现Thread-1还没有结束(Thread-1需要运行3秒才结束,现在还剩2秒),因此发生timeout,转而继续对Thread-2执行join操作。此次此刻,Thread-3恰巧结束,输入调试语句。
又过去1秒(总共运行了2秒),main thread发现Thread-2也没有结束(Thread-2需要运行4秒才结束,现在还剩2秒),因此同样发生timeout,继续对Thread-3执行join操作。由于Thread-3之前已结束,转而对Thread-4执行join操作。
再过去1秒(总共运行了3秒),main thread发现Thread-4没有结束(Thread-4需要5秒运行,现在还剩2秒),因此发生timeout,继续对Thread-5执行join操作。此时,Thread-1和Thread-5恰巧结束,输出调试语句。
main thread已经完成了对所有需要join的线程的观察和超时,因此main thread线程可以结束了。
时间又经过1秒,Thread-2结束。
再经过1秒,Thread-4结束。
后台线程
默认情况下,主线程在退出时会等待所有子线程的结束。如果希望主线程不等待子线程,而是在退出时自动结束所有的子线程,就需要设置子线程为后台线程(daemon)。方法是通过调用线程类的setDaemon()方法。如下:
- import threading
- import random
- import time
- class MyThread(threading.Thread):
- def run(self):
- wait_time=random.randrange(1,10)
- print "%s will wait %d seconds" % (self.name, wait_time)
- time.sleep(wait_time)
- print "%s finished!" % self.name
- if __name__=="__main__":
- print 'main thread is waitting for exit...'
- for i in range(5):
- t = MyThread()
- t.setDaemon(True)
- t.start()
-
- print 'main thread finished!'
执行结果:
main thread is waitting for exit...Thread-1 will wait 3 secondsThread-2 will wait 3 secondsThread-3 will wait 4 secondsThread-4 will wait 7 secondsThread-5 will wait 7 secondsmain thread finished!main thread is waitting for exit...Thread-1 will wait 3 secondsThread-2 will wait 3 secondsThread-3 will wait 4 secondsThread-4 will wait 7 secondsThread-5 will wait 7 secondsmain thread finished!
可以看出,主线程没有等待子线程的执行,而直接退出。
小结
join()方法使得线程可以等待另一个线程的运行,而setDaemon()方法使得线程在结束时不等待子线程。join和setDaemon都可以改变线程之间的运行顺序。
<span style="font-size:24px;">the father thread and the son thread are done</span>
相关文章