首页 > 代码库 > python趣味详解多线程
python趣味详解多线程
python3的多线程很多人无法理解是怎么运行的,因此本文从程序猿的日常生活出发,写了一个由浅入深的多线程教程,这样子大家就不会觉得陌生了,多线程真的很简单很简单!
假设我是一个程序猿,我想听歌,但是我又要打码,所以有:
我听完歌就去打码:
1 #!/usr/bin/python3.4 2 # -*- coding: utf-8 -*- 3 4 import time 5 6 def matter1(music): 7 print("我想听这些歌") 8 9 for i in range(0,len(music)):10 print("第" + str(i + 1) + "首歌是:" + str(music[i]))11 # 当前时间为12 print(time.strftime(‘%Y%H%M%S‘, time.localtime()))13 # 假设每一首歌曲的时间是2秒14 time.sleep(2)15 print("切换下一首歌...")16 17 def matter2(number):18 print("我在打码")19 20 j = 021 while j <= number:22 print("我准备写入第" + str(j + 1) +"行代码")23 j = j + 124 # 当前时间为25 print(time.strftime(‘%Y%H%M%S‘, time.localtime()))26 # 假设每写一行代码的时间为1秒27 time.sleep(1)28 print("写下一行代码...")29 30 if __name__ == ‘__main__‘:31 32 start = time.time()33 34 # 设定我要听的歌为35 music = ["music1","music2","music3"]36 # 开始听歌37 matter1(music)38 # 设定我要打码的行数39 number = 540 # 开始打码41 matter2(number)42 43 end = time.time()44 print("完成的时间为:" + str(end - start))
记录来的完成时间为:
完成的时间为:12.007483959197998
时间上完全符合,但是身为一个程序猿,可以一边打码一边听歌,那么设计一个多线程,让他们同时进行:
1 #!/usr/bin/python3.4 2 # -*- coding: utf-8 -*- 3 4 import time 5 import threading 6 7 def matter1(music): 8 print("我想听这些歌") 9 10 for i in range(0,len(music)):11 print("第" + str(i + 1) + "首歌是:" + str(music[i]))12 # 当前时间为13 print(time.strftime(‘%Y%H%M%S‘, time.localtime()))14 # 假设每一首歌曲的时间是2秒15 time.sleep(2)16 print("切换下一首歌...")17 18 def matter2(number):19 print("我在打码")20 21 j = 022 while j <= number:23 print("我准备写入第" + str(j + 1) +"行代码")24 j = j + 125 # 当前时间为26 print(time.strftime(‘%Y%H%M%S‘, time.localtime()))27 # 假设每写一行代码的时间为1秒28 time.sleep(1)29 print("写下一行代码...")30 31 if __name__ == ‘__main__‘:32 # 设定我要听的歌为33 music = ["music1","music2","music3"]34 35 # 设定我要打码的行数36 number = 537 # 建立一个新数组38 threads = []39 # 将听歌放入数组里面40 thing1 = threading.Thread(target=matter1, args=(music,))41 threads.append(thing1)42 # 将打码放入数组里面43 thing2 = threading.Thread(target=matter2, args=(number,))44 threads.append(thing2)45 46 # 开始时间47 start = time.time()48 # 写个for让两件事情都进行49 for thing in threads:50 # setDaemon为主线程启动了线程matter1和matter251 # 启动也就是相当于执行了这个for循环52 thing.setDaemon(True)53 thing.start()54 55 # 结束时间56 end = time.time()57 print("完成的时间为:" + str(end - start))
但是直接就结束了?
完成的时间为:0.0010008811950683594
原来是setDaemon,主线程启动两个子线程后做事后,主线程就不管子线程是否运行完毕,直接往下运行,直接运行到
print("完成的时间为:" + str(end - start))
然后程序就结束了,因此,为了防止子线程还没结束主线程就结束的意外情况,在程序里面加个join:
1 #!/usr/bin/python3.4 2 # -*- coding: utf-8 -*- 3 4 import time 5 import threading 6 7 def matter1(music): 8 print("我想听这些歌") 9 10 for i in range(0,len(music)):11 print("第" + str(i + 1) + "首歌是:" + str(music[i]))12 # 当前时间为13 print(time.strftime(‘%Y%H%M%S‘, time.localtime()))14 # 假设每一首歌曲的时间是2秒15 time.sleep(2)16 print("切换下一首歌...")17 18 def matter2(number):19 print("我在打码")20 21 j = 022 while j <= number:23 print("我准备写入第" + str(j + 1) +"行代码")24 j = j + 125 # 当前时间为26 print(time.strftime(‘%Y%H%M%S‘, time.localtime()))27 # 假设每写一行代码的时间为1秒28 time.sleep(1)29 print("写下一行代码...")30 31 if __name__ == ‘__main__‘:32 # 设定我要听的歌为33 music = ["music1","music2","music3"]34 35 # 设定我要打码的行数36 number = 537 # 建立一个新数组38 threads = []39 # 将听歌放入数组里面40 thing1 = threading.Thread(target=matter1, args=(music,))41 threads.append(thing1)42 # 将打码放入数组里面43 thing2 = threading.Thread(target=matter2, args=(number,))44 threads.append(thing2)45 46 # 开始时间47 start = time.time()48 # 写个for让两件事情都进行49 for thing in threads:50 # setDaemon为主线程启动了线程matter1和matter251 # 启动也就是相当于执行了这个for循环52 thing.setDaemon(True)53 thing.start()54 55 # 子线程没结束前主线程会被卡在这里56 thing.join()57 # 结束时间58 end = time.time()59 print("完成的时间为:" + str(end - start))
最后运行的时间就是打码的时间:
完成的时间为:6.003339052200317
这就真正做到了一边听歌一边打码的双手互博的状态,本文后面的那0.003333秒就别纠结了,系统运行程序花个0.0033333秒不过分吧
偷懒打码打4行:
number = 4完成的时间为:5.008083820343018
------------------------------我是快乐的分割线------------------------------
网上的多线程都是写成“类”的形式,这里写成函数不符合“大众”标准,那么就改成类的形式:
1 #!/usr/bin/python3.4 2 # -*- coding: utf-8 -*- 3 4 import time 5 import threading 6 7 class MyThread(threading.Thread): 8 def __init__(self, func, args, name=‘‘): 9 threading.Thread.__init__(self)10 self.name = name11 self.func = func12 self.args = args13 #self.counter = counter14 15 def run(self):16 # 某某线程要开始了17 print(self.name + "开始了##################")18 19 if self.name == "听歌线程":20 matter1(music)21 elif self.name == "打码线程":22 matter2(number)23 print(self.name + "结束了##################")24 25 def matter1(music):26 for i in range(0,len(music)):27 print("第" + str(i + 1) + "首歌是:" + str(music[i]))28 # 假设每一首歌曲的时间是2秒29 time.sleep(2)30 print("切换下一首歌...")31 32 def matter2(number):33 j = 034 while j <= number:35 print("我准备写入第" + str(j + 1) +"行代码")36 j = j + 137 # 假设每写一行代码的时间为1秒38 time.sleep(1)39 print("写下一行代码...")40 41 42 if __name__ == ‘__main__‘:43 # 设定我要听的歌为44 music = ["music1","music2","music3"]45 46 # 设定我要打码的行数47 number = 448 49 # 开始时间50 start = time.time()51 52 thing1 = MyThread(matter1, music,"听歌线程")53 thing2 = MyThread(matter2, number, "打码线程")54 thing1.start()55 thing2.start()56 thing1.join()57 thing2.join()58 59 # 结束时间60 end = time.time()61 print("完成的时间为:" + str(end - start))
运行结果也是6秒:
完成的时间为:6.001942157745361
----------------------我是快乐的分割线-------------------------
程序猿在跑代码的时候是很无聊的,无聊的时候就会想到去吃零食,那么我就加入一个函数:
1 #!/usr/bin/python3.4 2 # -*- coding: utf-8 -*- 3 4 import time 5 import threading 6 7 class MyThread(threading.Thread): 8 def __init__(self, func, args, name=‘‘): 9 threading.Thread.__init__(self)10 self.name = name11 self.func = func12 self.args = args13 #self.counter = counter14 15 def run(self):16 # 某某线程要开始了17 print(self.name + "开始了##################")18 19 if self.name == "听歌线程":20 matter1(music)21 elif self.name == "打码线程":22 matter2(number)23 elif self.name == "零食线程":24 matter3(snacks)25 print(self.name + "结束了##################")26 27 def matter1(music):28 for i in range(0,len(music)):29 print("第" + str(i + 1) + "首歌是:" + str(music[i]))30 # 假设每一首歌曲的时间是2秒31 time.sleep(2)32 print("切换下一首歌...")33 34 def matter2(number):35 j = 036 while j <= number:37 print("我准备写入第" + str(j + 1) +"行代码")38 j = j + 139 # 假设每写一行代码的时间为1秒40 time.sleep(1)41 print("写下一行代码...")42 43 def matter3(snacks):44 for k in range(0,len(snacks)):45 print("我正在听着歌吃" + str(snacks[k]) + "零食")46 #每吃一袋零食间隔5秒47 time.sleep(5)48 print("吃完了一包零食")49 50 if __name__ == ‘__main__‘:51 # 设定我要听的歌为52 music = ["music1","music2","music3"]53 54 # 设定我要打码的行数55 number = 456 57 # 设定我想吃的零食58 snacks = ["咪咪","辣条"]59 60 # 开始时间61 start = time.time()62 63 thing1 = MyThread(matter1, music,"听歌线程")64 thing2 = MyThread(matter2, number, "打码线程")65 thing3 = MyThread(matter3, snacks, "零食线程")66 thing1.start()67 thing2.start()68 thing3.start()69 thing1.join()70 thing2.join()71 thing3.join()72 73 # 结束时间74 end = time.time()75 print("完成的时间为:" + str(end - start))
程序运行的时间是:
完成的时间为:10.000968933105469
感觉还是吃零食比较耗时间。但是但是,程序猿只有两个手,那么吃零食和打码是不能同时进行了,那么这里加个线程锁:
1 #!/usr/bin/python3.4 2 # -*- coding: utf-8 -*- 3 4 import time 5 import threading 6 7 # 打开线程锁 8 lock = threading.Lock() 9 10 class MyThread(threading.Thread):11 def __init__(self, func, args, name=‘‘):12 threading.Thread.__init__(self)13 self.name = name14 self.func = func15 self.args = args16 #self.counter = counter17 18 def run(self):19 # 某某线程要开始了20 print(self.name + "开始了##################")21 22 if self.name == "听歌线程":23 matter1(music)24 elif self.name == "打码线程":25 matter2(number)26 elif self.name == "零食线程":27 matter3(snacks)28 print(self.name + "结束了##################")29 30 def matter1(music):31 for i in range(0,len(music)):32 print("第" + str(i + 1) + "首歌是:" + str(music[i]))33 # 假设每一首歌曲的时间是2秒34 time.sleep(2)35 print("切换下一首歌...")36 37 def matter2(number):38 lock.acquire()39 j = 040 while j <= number:41 print("我准备写入第" + str(j + 1) +"行代码")42 j = j + 143 # 假设每写一行代码的时间为1秒44 time.sleep(1)45 print("写下一行代码...")46 lock.release()47 48 def matter3(snacks):49 lock.acquire()50 for k in range(0,len(snacks)):51 print("我正在听着歌吃" + str(snacks[k]) + "零食")52 #每吃一袋零食间隔5秒53 time.sleep(5)54 print("吃完了一包零食")55 lock.release()56 57 if __name__ == ‘__main__‘:58 # 设定我要听的歌为59 music = ["music1","music2","music3"]60 61 # 设定我要打码的行数62 number = 463 64 # 设定我想吃的零食65 snacks = ["咪咪","辣条"]66 67 # 开始时间68 start = time.time()69 70 thing1 = MyThread(matter1, music,"听歌线程")71 thing2 = MyThread(matter2, number, "打码线程")72 thing3 = MyThread(matter3, snacks, "零食线程")73 thing1.start()74 thing2.start()75 thing3.start()76 thing1.join()77 thing2.join()78 thing3.join()79 80 # 结束时间81 end = time.time()82 print("完成的时间为:" + str(end - start))
运行时间为:
完成的时间为:15.001857995986938
这里解释一下:
只是听歌和打码花的时间是5s多;听歌、打码、吃零食同时进行是10s多;
加了线程锁后,打码和吃零食不能同时进行,那么就变成:
听歌和打码花的时间是5s多;单独吃零食是10s多,加起来就是15秒;
为了验证吃零食的时候还是听着歌的,所以将听歌的时间间隔改成10s,得到的运行时间为:
完成的时间为:30.000711917877197
运行结果贴出来看一下:
1 听歌线程开始了################## 2 第1首歌是:music1 3 打码线程开始了################## 4 我准备写入第1行代码 5 零食线程开始了################## 6 写下一行代码... 7 我准备写入第2行代码 8 写下一行代码... 9 我准备写入第3行代码10 写下一行代码...11 我准备写入第4行代码12 写下一行代码...13 我准备写入第5行代码14 写下一行代码...15 打码线程结束了##################16 我正在听着歌吃咪咪零食17 切换下一首歌...18 第2首歌是:music219 吃完了一包零食20 我正在听着歌吃辣条零食21 吃完了一包零食22 零食线程结束了##################23 切换下一首歌...24 第3首歌是:music325 切换下一首歌...26 听歌线程结束了##################
perfect!
转载请注明出处:https://i.cnblogs.com/EditPosts.aspx?postid=5846745
python趣味详解多线程