51Testing软件测试论坛

 找回密码
 (注-册)加入51Testing

QQ登录

只需一步,快速开始

微信登录,快人一步

手机号码,快捷登录

查看: 1799|回复: 2
打印 上一主题 下一主题

python3多线程趣味详解

[复制链接]

该用户从未签到

跳转到指定楼层
1#
发表于 2018-4-23 13:50:57 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
假设我是一个程序猿,我想听歌,但是我又要打码,所以有:

我听完歌就去打码:

复制代码

  1. 1 #!/usr/bin/python3.4
  2. 2 # -*- coding: utf-8 -*-
  3. 3
  4. 4 import time
  5. 5
  6. 6 def matter1(music):
  7. 7     print("我想听这些歌")
  8. 8
  9. 9     for i in range(0,len(music)):
  10. 10         print("第" + str(i + 1) + "首歌是:" + str(music[i]))
  11. 11         # 当前时间为
  12. 12         print(time.strftime('%Y%H%M%S', time.localtime()))
  13. 13         # 假设每一首歌曲的时间是2秒
  14. 14         time.sleep(2)
  15. 15         print("切换下一首歌...")
  16. 16
  17. 17 def matter2(number):
  18. 18     print("我在打码")
  19. 19
  20. 20     j = 0
  21. 21     while j <= number:
  22. 22         print("我准备写入第" + str(j + 1) +"行代码")
  23. 23         j = j + 1
  24. 24         # 当前时间为
  25. 25         print(time.strftime('%Y%H%M%S', time.localtime()))
  26. 26         # 假设每写一行代码的时间为1秒
  27. 27         time.sleep(1)
  28. 28         print("写下一行代码...")
  29. 29
  30. 30 if __name__ == '__main__':
  31. 31
  32. 32     start = time.time()
  33. 33
  34. 34     # 设定我要听的歌为
  35. 35     music = ["music1","music2","music3"]
  36. 36     # 开始听歌
  37. 37     matter1(music)
  38. 38     # 设定我要打码的行数
  39. 39     number = 5
  40. 40     # 开始打码
  41. 41     matter2(number)
  42. 42
  43. 43     end = time.time()
  44. 44     print("完成的时间为:" + str(end - start))
复制代码

复制代码
记录来的完成时间为:

1
完成的时间为:12.007483959197998
时间上完全符合,但是身为一个程序猿,可以一边打码一边听歌,那么设计一个多线程,让他们同时进行:

复制代码

  1. 1 #!/usr/bin/python3.4
  2. 2 # -*- coding: utf-8 -*-
  3. 3
  4. 4 import time
  5. 5 import threading
  6. 6
  7. 7 def matter1(music):
  8. 8     print("我想听这些歌")
  9. 9
  10. 10     for i in range(0,len(music)):
  11. 11         print("第" + str(i + 1) + "首歌是:" + str(music[i]))
  12. 12         # 当前时间为
  13. 13         print(time.strftime('%Y%H%M%S', time.localtime()))
  14. 14         # 假设每一首歌曲的时间是2秒
  15. 15         time.sleep(2)
  16. 16         print("切换下一首歌...")
  17. 17
  18. 18 def matter2(number):
  19. 19     print("我在打码")
  20. 20
  21. 21     j = 0
  22. 22     while j <= number:
  23. 23         print("我准备写入第" + str(j + 1) +"行代码")
  24. 24         j = j + 1
  25. 25         # 当前时间为
  26. 26         print(time.strftime('%Y%H%M%S', time.localtime()))
  27. 27         # 假设每写一行代码的时间为1秒
  28. 28         time.sleep(1)
  29. 29         print("写下一行代码...")
  30. 30
  31. 31 if __name__ == '__main__':
  32. 32     # 设定我要听的歌为
  33. 33     music = ["music1","music2","music3"]
  34. 34
  35. 35     # 设定我要打码的行数
  36. 36     number = 5
  37. 37     # 建立一个新数组
  38. 38     threads = []
  39. 39     # 将听歌放入数组里面
  40. 40     thing1 = threading.Thread(target=matter1, args=(music,))
  41. 41     threads.append(thing1)
  42. 42     # 将打码放入数组里面
  43. 43     thing2 = threading.Thread(target=matter2, args=(number,))
  44. 44     threads.append(thing2)
  45. 45
  46. 46     # 开始时间
  47. 47     start = time.time()
  48. 48     # 写个for让两件事情都进行
  49. 49     for thing in threads:
  50. 50         # setDaemon为主线程启动了线程matter1和matter2
  51. 51         # 启动也就是相当于执行了这个for循环
  52. 52         thing.setDaemon(True)
  53. 53         thing.start()
  54. 54
  55. 55     # 结束时间
  56. 56     end = time.time()
  57. 57     print("完成的时间为:" + str(end - start))
复制代码

复制代码
但是直接就结束了?

1
完成的时间为:0.0010008811950683594
原来是setDaemon,主线程启动两个子线程后做事后,主线程就不管子线程是否运行完毕,直接往下运行,
直接运行到

1
print("完成的时间为:" + str(end - start))
然后程序就结束了,因此,为了防止子线程还没结束主线程就结束的意外情况,在程序里面加个join:

复制代码

  1. 1 import time
  2. 2 import threading
  3. 3
  4. 4 def matter1(music):
  5. 5     print("我想听这些歌")
  6. 6
  7. 7     for i in range(0,len(music)):
  8. 8         print("第" + str(i + 1) + "首歌是:" + str(music[i]))
  9. 9         # 当前时间为
  10. 10         print(time.strftime('%Y%H%M%S', time.localtime()))
  11. 11         # 假设每一首歌曲的时间是2秒
  12. 12         time.sleep(2)
  13. 13         print("切换下一首歌...")
  14. 14
  15. 15 def matter2(number):
  16. 16     print("我在打码")
  17. 17
  18. 18     j = 0
  19. 19     while j <= number:
  20. 20         print("我准备写入第" + str(j + 1) +"行代码")
  21. 21         j = j + 1
  22. 22         # 当前时间为
  23. 23         print(time.strftime('%Y%H%M%S', time.localtime()))
  24. 24         # 假设每写一行代码的时间为1秒
  25. 25         time.sleep(1)
  26. 26         print("写下一行代码...")
  27. 27
  28. 28 if __name__ == '__main__':
  29. 29     # 设定我要听的歌为
  30. 30     music = ["music1","music2","music3"]
  31. 31
  32. 32     # 设定我要打码的行数
  33. 33     number = 5
  34. 34     # 建立一个新数组
  35. 35     threads = []
  36. 36     # 将听歌放入数组里面
  37. 37     thing1 = threading.Thread(target=matter1, args=(music,))
  38. 38     threads.append(thing1)
  39. 39     # 将打码放入数组里面
  40. 40     thing2 = threading.Thread(target=matter2, args=(number,))
  41. 41     threads.append(thing2)
  42. 42
  43. 43     # 开始时间
  44. 44     start = time.time()
  45. 45     # 写个for让两件事情都进行
  46. 46     for thing in threads:
  47. 47         # setDaemon为主线程启动了线程matter1和matter2
  48. 48         # 启动也就是相当于执行了这个for循环
  49. 49         thing.setDaemon(True)
  50. 50         thing.start()
  51. 51
  52. 52     # 子线程没结束前主线程会被卡在这里
  53. 53     thing1.join()
  54. 54     thing2.join()
  55. 55     # 结束时间
  56. 56     end = time.time()
  57. 57     print("完成的时间为:" + str(end - start))
复制代码

复制代码


最后运行的时间就是打码的时间:

1
完成的时间为:6.003339052200317
这就真正做到了一边听歌一边打码的双手互博的状态,本文后面的那0.003333秒就别纠结了,系统运行程序
花个0.0033333秒不过分吧

偷懒打码打4行:

1
2
number = 4
完成的时间为:5.008083820343018
------------------------------我是快乐的分割线------------------------------

网上的多线程都是写成“类”的形式,这里写成函数不符合“大众”标准,那么就改成类的形式:

复制代码

  1. 1 #!/usr/bin/python3.4
  2. 2 # -*- coding: utf-8 -*-
  3. 3
  4. 4 import time
  5. 5 import threading
  6. 6
  7. 7 class MyThread(threading.Thread):
  8. 8     def __init__(self, func, args, name=''):
  9. 9         threading.Thread.__init__(self)
  10. 10         self.name = name
  11. 11         self.func = func
  12. 12         self.args = args
  13. 13         #self.counter = counter
  14. 14
  15. 15     def run(self):
  16. 16         # 某某线程要开始了
  17. 17         print(self.name + "开始了##################")
  18. 18
  19. 19         if self.name == "听歌线程":
  20. 20             matter1(music)
  21. 21         elif self.name == "打码线程":
  22. 22             matter2(number)
  23. 23         print(self.name + "结束了##################")
  24. 24
  25. 25 def matter1(music):
  26. 26     for i in range(0,len(music)):
  27. 27         print("第" + str(i + 1) + "首歌是:" + str(music[i]))
  28. 28         # 假设每一首歌曲的时间是2秒
  29. 29         time.sleep(2)
  30. 30         print("切换下一首歌...")
  31. 31
  32. 32 def matter2(number):
  33. 33     j = 0
  34. 34     while j <= number:
  35. 35         print("我准备写入第" + str(j + 1) +"行代码")
  36. 36         j = j + 1
  37. 37         # 假设每写一行代码的时间为1秒
  38. 38         time.sleep(1)
  39. 39         print("写下一行代码...")
  40. 40
  41. 41
  42. 42 if __name__ == '__main__':
  43. 43     # 设定我要听的歌为
  44. 44     music = ["music1","music2","music3"]
  45. 45
  46. 46     # 设定我要打码的行数
  47. 47     number = 4
  48. 48
  49. 49     # 开始时间
  50. 50     start = time.time()
  51. 51
  52. 52     thing1 = MyThread(matter1, music,"听歌线程")
  53. 53     thing2 = MyThread(matter2, number, "打码线程")
  54. 54     thing1.start()
  55. 55     thing2.start()
  56. 56     thing1.join()
  57. 57     thing2.join()
  58. 58
  59. 59     # 结束时间
  60. 60     end = time.time()
  61. 61     print("完成的时间为:" + str(end - start))
复制代码




分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏
回复

使用道具 举报

该用户从未签到

2#
 楼主| 发表于 2018-4-23 13:51:30 | 只看该作者
复制代码
运行结果也是6秒:

1
完成的时间为: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))
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))

复制代码
程序运行的时间是:

1
完成的时间为: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))
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))

复制代码
运行时间为:

1
完成的时间为:15.001857995986938
这里解释一下:

1
2
3
只是听歌和打码花的时间是5s多;

听歌、打码、吃零食同时进行是10s多;
加了线程锁后,打码和吃零食不能同时进行,那么就变成:

1
2
3
听歌和打码花的时间是5s多;

单独吃零食是10s多,加起来就是15秒;
为了验证吃零食的时候还是听着歌的,所以将听歌的时间间隔改成10s,得到的运行时间为:

1
完成的时间为: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 听歌线程结束了##################
回复 支持 反对

使用道具 举报

本版积分规则

关闭

站长推荐上一条 /1 下一条

小黑屋|手机版|Archiver|51Testing软件测试网 ( 沪ICP备05003035号 关于我们

GMT+8, 2024-11-18 00:23 , Processed in 0.064781 second(s), 23 queries .

Powered by Discuz! X3.2

© 2001-2024 Comsenz Inc.

快速回复 返回顶部 返回列表