分析:一个py文件调用两个方法(loop0和loop1),loop0执行耗时4s,loop1执行耗时2s。分别使用不同的实现方式,比较完成两个方法的运行实际耗时
1)、普通实现(耗时较长,至少为两个函数耗时的并集)。代码示例:
import time from time import sleep #定义loop0函数,loop0函数运行完需要4s def loop0(): print("loop0开始,当前时间为:",time.asctime()) sleep(4) print("loop0结束:当前时间为:",time.asctime()) #定义loop1函数,loop1函数运行完需要4s def loop1(): print("loop1开始,当前时间为:",time.asctime()) sleep(2) print("loop1结束,当前时间为:",time.asctime()) #定义main函数,main函数调用loop0和loop1,运行耗时至少4+2=6s(即为所有调用函数耗时的并集) def main(): print("所有开始,当前时间为:",time.asctime()) loop0() loop1() print("所有结束,当前时间为:",time.asctime()) if __name__ == ‘__main__‘: main()
2)使用_thread管理多线程(普通实现,不考虑加锁)(这种方式需要自己定义子线程执行过程中主线程等待的时长)。代码示例:
# 多线程new import _thread import time from time import sleep def loop0(): print("loop0开始,当前时间为:", time.asctime()) sleep(4) print("loop0结束:当前时间为:", time.asctime()) def loop1(): print("loop1开始,当前时间为:", time.asctime()) sleep(2) print("loop1结束,当前时间为:", time.asctime()) def main(): print("所有开始,当前时间为:", time.asctime()) _thread.start_new_thread(loop0,()) #线程1 _thread.start_new_thread(loop1,()) #线程2 sleep(4.1) print("所有结束,当前时间为:", time.asctime()) #主线程 if __name__ == ‘__main__‘: main()
3)使用_thread管理多线程(配上加锁)(这种方式不需要自己定义子线程执行过程中主线程等待的时长,使用子线程的锁是否都释放完去判断)。代码示例:
# 在2)的基础上改进,不自己去定义等待时间防止主线程退出。而是给子线程加锁解锁的方式,去判断子线程是否执行完毕再退出 # 使用_thread,需要先根据子线程数上锁。每调用执行完一个子线程,释放一个锁。最后在主线程结束前,去判断所有的锁是否都释放完(否则,进入死循环中,目的是保证,不让主线程退出) import _thread import time from time import sleep loops = [4, 2] def loop(loopn, t, l): print(loopn, "开始,当前时间为:", time.asctime()) sleep(t) print(loopn, "结束:当前时间为:", time.asctime()) l.release() def main(): print("所有开始,当前时间为:", time.asctime()) locks = [] loopn = ["loop0", "loop1"] nloops = range(len(loops)) for i in nloops: lock = _thread.allocate_lock() lock.acquire() locks.append(lock) for i in nloops: _thread.start_new_thread(loop, (loopn[i], loops[i], locks[i])) for i in nloops: while locks[i].locked(): pass print("所有结束,当前时间为:", time.asctime()) # 主线程 if __name__ == ‘__main__‘: main()
4)使用threadding管理多线程(不需要加锁,用Thread自带的join实现阻塞主线程退出的动作,从而使得子线程都能运行完毕)。代码示例如下:
# 和_thread不同,使用threading.thread。不需要手动去加锁、释放锁。使用threading.thread会得到一个返回值t。将t放到列表list中 # list[i].start子线程才会启动,t.join保证子线程运行结束,才会退出主线程 # 一定要join,不然主线程比子线程跑的快,就会出错 import _thread import threading import time from time import sleep loops = [4, 2] def loop(loopn, t): print(loopn, "开始,当前时间为:", time.asctime()) sleep(t) print(loopn, "结束:当前时间为:", time.asctime()) def main(): print("所有开始,当前时间为:", time.asctime()) loopn = ["loop0", "loop1"] nloops = range(len(loops)) threads=[] for i in nloops: t=threading.Thread(target=loop,args=(loopn[i],loops[i])) threads.append(t) for i in nloops: threads[i].start() for i in nloops: threads[i].join() print("所有结束,当前时间为:", time.asctime()) # 主线程 if __name__ == ‘__main__‘: main()
5)自己定义一个继承threading.Thread的类,调用Thread的构造,重写run方法,达到直接用自己定义的类去实现多线程的管理。代码示例:
# threading另一种方法的调用。定义一个类,去继承thread。继承后,主动去掉父类的init方法。主动调用后,再重写run方法。 # 比较推荐的方法,面向对象的接口编程思想 import _thread import threading import time from time import sleep loops = [4, 2] # 主动调构造方法 class Mythread(threading.Thread): def __init__(self, func, args): threading.Thread.__init__(self) self.func = func self.args = args def run(self): self.func(*self.args) def loop(loopn, t): print(loopn, "开始,当前时间为:", time.asctime()) sleep(t) print(loopn, "结束:当前时间为:", time.asctime()) def main(): print("所有开始,当前时间为:", time.asctime()) loopn = ["loop0", "loop1"] nloops = range(len(loops)) threads = [] for i in nloops: t = Mythread(loop, (loopn[i],loops[i])) threads.append(t) for i in nloops: threads[i].start() for i in nloops: threads[i].join() print("所有结束,当前时间为:", time.asctime()) # 主线程 if __name__ == ‘__main__‘: main()
原文:https://www.cnblogs.com/Brynaaa/p/14527039.html