首页 > 代码库 > 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趣味详解多线程