多线程 python3_python3多线程趣味详解

python3的多线程很多人无法理解是怎么运行的,因此本文从程序猿的日常生活出发,写了一个由浅入深的多线程教程,这样子大家就不会觉得陌生了,多线程真的很简单很简单!

不要讲多线程局限于库或者框架,自己造轮子才是最大的快乐。

-----------------------------------------以下是正文--------------------------------------------

假设我是一个程序猿,我想听歌,但是我又要打码,所以有:

我听完歌就去打码:

1 #!/usr/bin/python3.4

2 #-*- coding: utf-8 -*-

3

4 importtime5

6 defmatter1(music):7 print("我想听这些歌")8

9 for i inrange(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 defmatter2(number):18 print("我在打码")19

20 j =021 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 importtime5 importthreading6

7 defmatter1(music):8 print("我想听这些歌")9

10 for i inrange(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 defmatter2(number):19 print("我在打码")20

21 j =022 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 inthreads: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 importtime2 importthreading3

4 defmatter1(music):5 print("我想听这些歌")6

7 for i inrange(0,len(music)):8 print("第" + str(i + 1) + "首歌是:" +str(music[i]))9 #当前时间为

10 print(time.strftime('%Y%H%M%S', time.localtime()))11 #假设每一首歌曲的时间是2秒

12 time.sleep(2)13 print("切换下一首歌...")14

15 defmatter2(number):16 print("我在打码")17

18 j =019 while j <=number:20 print("我准备写入第" + str(j + 1) +"行代码")21 j = j + 1

22 #当前时间为

23 print(time.strftime('%Y%H%M%S', time.localtime()))24 #假设每写一行代码的时间为1秒

25 time.sleep(1)26 print("写下一行代码...")27

28 if __name__ == '__main__':29 #设定我要听的歌为

30 music = ["music1","music2","music3"]31

32 #设定我要打码的行数

33 number = 5

34 #建立一个新数组

35 threads =[]36 #将听歌放入数组里面

37 thing1 = threading.Thread(target=matter1, args=(music,))38 threads.append(thing1)39 #将打码放入数组里面

40 thing2 = threading.Thread(target=matter2, args=(number,))41 threads.append(thing2)42

43 #开始时间

44 start =time.time()45 #写个for让两件事情都进行

46 for thing inthreads:47 #setDaemon为主线程启动了线程matter1和matter2

48 #启动也就是相当于执行了这个for循环

49 thing.setDaemon(True)50 thing.start()51

52 #子线程没结束前主线程会被卡在这里

53 thing1.join()54 thing2.join()55 #结束时间

56 end =time.time()57 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 importtime5 importthreading6

7 classMyThread(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 = counter

14

15 defrun(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 defmatter1(music):26 for i inrange(0,len(music)):27 print("第" + str(i + 1) + "首歌是:" +str(music[i]))28 #假设每一首歌曲的时间是2秒

29 time.sleep(2)30 print("切换下一首歌...")31

32 defmatter2(number):33 j =034 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 importtime5 importthreading6

7 classMyThread(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 = counter

14

15 defrun(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 defmatter1(music):28 for i inrange(0,len(music)):29 print("第" + str(i + 1) + "首歌是:" +str(music[i]))30 #假设每一首歌曲的时间是2秒

31 time.sleep(2)32 print("切换下一首歌...")33

34 defmatter2(number):35 j =036 while j <=number:37 print("我准备写入第" + str(j + 1) +"行代码")38 j = j + 1

39 #假设每写一行代码的时间为1秒

40 time.sleep(1)41 print("写下一行代码...")42

43 defmatter3(snacks):44 for k inrange(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 importtime5 importthreading6

7 #打开线程锁

8 lock =threading.Lock()9

10 classMyThread(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 = counter

17

18 defrun(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 defmatter1(music):31 for i inrange(0,len(music)):32 print("第" + str(i + 1) + "首歌是:" +str(music[i]))33 #假设每一首歌曲的时间是2秒

34 time.sleep(2)35 print("切换下一首歌...")36

37 defmatter2(number):38 lock.acquire()39 j =040 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 defmatter3(snacks):49 lock.acquire()50 for k inrange(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首歌是:music13 打码线程开始了##################

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!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值