threading模块提供了管理多个线程执行的API。
最简单的用法。就是用一个目标函数实例化一个Thread对象。start()开始工作,join()等待当前线程完成。
1: import threading2: def work():3: print("working")4: for i in range(5):5: t = threading.Thread(target=work)6: t.start()7: print("please wait!")8: t.join()
结果
1: working2: please wait!3: working4: please wait!5: working6: please wait!7: working8: please wait!9: working10: please wait!
当然也可以传递参数。
1: import threading2: def work(i):3: print("%i is working" %i)4: for i in range(5):5: t = threading.Thread(target=work,args=(i,))6: t.start()7: print("please wait!")8: t.join()
结果
1: 0 is working2: please wait!3: 1 is working4: please wait!5: 2 is working6: please wait!7: 3 is working8: please wait!9: 4 is working10: please wait!
每个Thread实例都有一个带有默认值的名字,也可以传入name参数更改。
1: import threading2: import time3: def work():4: print(threading.current_thread().getName(),"starting!")5: time.sleep(0.5)6: print(threading.current_thread().getName(),"end!")7:8: t = threading.Thread(name="worker", target=work)9: t.start()10: print("please wait!")11: t.join()
结果
1: worker starting!2: please wait!3: worker end!
出于线程安全的考虑,我们下面用logging模块输出消息。
一般来说,程序都会等待所有线程完成工作之后才退出。而守护线程可以一直运行而不阻塞主程序的退出。传入daemon=True或者调用setDaemon()方法并提供参数True来构造守护线程。
1: import threading2: import time3: import logging4: def daemon():5: logging.debug("start")6: time.sleep(0.5)7: logging.debug("exite")8: def non_deamon():9: logging.debug("start")10: logging.debug("exit")11: logging.basicConfig(12: level=logging.DEBUG,13: format=‘(%(threadName)-10s) %(message)s‘,14: )15: d = threading.Thread(name=‘deamon‘, target=daemon, daemon=True)16: t = threading.Thread(name="non-deamon", target=non_deamon)17: d.start()18: t.start()
结果中没有看到守护线程的退出的消息,主程序就已经退出了。
1: (deamon ) start2: (non-deamon) start3: (non-deamon) exit
要等待一个守护线程结束,需要使用join()方法。默认下,join会无限阻塞,但可以传入浮点值。在时间内线程即使未完成,join也会强制返回。
1: import threading2: import time3: import logging4: def daemon():5: logging.debug("start")6: time.sleep(0.5)7: logging.debug("exite")8: def non_deamon():9: logging.debug("start")10: logging.debug("exit")11: logging.basicConfig(12: level=logging.DEBUG,13: format=‘(%(threadName)-10s) %(message)s‘,14: )15: d = threading.Thread(name=‘deamon‘, target=daemon, daemon=True)16: t = threading.Thread(name="non-deamon", target=non_deamon)17: d.start()18: d.join(0.2)19: t.start()
结果还是没有看到守护线程的结束退出的消息。
1: (deamon ) start2: (non-deamon) start3: (non-deamon) exit
threading.enumerate()会返回一个Thread实例的一个列表。由于等待当前主程序终止会引入一种死锁的情况,所以跳过这个线程等待。注意根据电脑配置,合理调节线程睡眠时间,否则会由于缺少logging参数而报错。
上述程序各个线程执行的顺序1: import threading2: import time3: import logging4: import random5: def worker():6: pause = random.randint(1, 5) / 27: logging.debug("sleeping %0.2f" % pause)8: time.sleep(pause)9: logging.debug("end!")10: logging.basicConfig(11: level=logging.DEBUG,12: format=‘(%(threadName)-10s) %(message)s‘,13: )14: for i in range(3):15: t = threading.Thread(target=worker, daemon=True)16: t.start()17: # 拿到当前主线程18: main_thread = threading.main_thread()19: for t in threading.enumerate():20: if t is main_thread:21: continue22: logging.debug("joining %s" % t.getName())23: t.join()
输出顺序可能不一样,
1: (Thread-1 ) sleeping 0.502: (Thread-2 ) sleeping 1.503: (Thread-3 ) sleeping 2.004: (MainThread) joining Thread-15: (Thread-1 ) end!6: (MainThread) joining Thread-27: (Thread-2 ) end!8: (MainThread) joining Thread-39: (Thread-3 ) end!
原文:https://www.cnblogs.com/haoqirui/p/10321194.html