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 = 0 21
- while j <= number: 22 print("我准备写入第" + str(j + 1) + "行代码") 23 j = j + 1 24#当前时间为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 = 5 40#开始打码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 = 0 22
- while j <= number: 23 print("我准备写入第" + str(j + 1) + "行代码") 24 j = j + 1 25#当前时间为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 = 5 37#建立一个新数组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和matter2 51#启动也就是相当于执行了这个
- 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 = 0 22
- while j <= number: 23 print("我准备写入第" + str(j + 1) + "行代码") 24 j = j + 1 25#当前时间为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 = 5 37#建立一个新数组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和matter2 51#启动也就是相当于执行了这个
- 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 = name 11 self.func = func 12 self.args = args 13#self.counter = counter 14 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 = 0 34
- while j <= number: 35 print("我准备写入第" + str(j + 1) + "行代码") 36 j = j + 1 37#假设每写一行代码的时间为1秒38 time.sleep(1) 39 print("写下一行代码...") 40 41 42
- if __name__ == '__main__': 43#设定我要听的歌为44 music = ["music1", "music2", "music3"] 45 46#设定我要打码的行数47 number = 4 48 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 = name 11 self.func = func 12 self.args = args 13#self.counter = counter 14 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 = 0 36
- while j <= number: 37 print("我准备写入第" + str(j + 1) + "行代码") 38 j = j + 1 39#假设每写一行代码的时间为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 = 4 56 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 = name 14 self.func = func 15 self.args = args 16#self.counter = counter 17 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 = 0 40
- while j <= number: 41 print("我准备写入第" + str(j + 1) + "行代码") 42 j = j + 1 43#假设每写一行代码的时间为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 = 4 63 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首歌是:music2 19吃完了一包零食20我正在听着歌吃辣条零食21吃完了一包零食22零食线程结束了##################23切换下一首歌...24第3首歌是:music3 25切换下一首歌...26听歌线程结束了##################
perfect!
来源: http://www.cnblogs.com/TTyb/p/5846745.html