小小糖 发表于 2018-4-23 13:50:57

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))
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))
复制代码
记录来的完成时间为:

1
完成的时间为: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))
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))
复制代码
但是直接就结束了?

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

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

复制代码

1 import time
2 import threading
3
4 def matter1(music):
5   print("我想听这些歌")
6
7   for i in range(0,len(music)):
8         print("第" + str(i + 1) + "首歌是:" + str(music))
9         # 当前时间为
10         print(time.strftime('%Y%H%M%S', time.localtime()))
11         # 假设每一首歌曲的时间是2秒
12         time.sleep(2)
13         print("切换下一首歌...")
14
15 def matter2(number):
16   print("我在打码")
17
18   j = 0
19   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 in threads:
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))
复制代码


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

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

偷懒打码打4行:

1
2
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))
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))



小小糖 发表于 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) + "零食")
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) + "零食")
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 听歌线程结束了##################

梦想家 发表于 2018-5-9 10:00:42

:victory:
页: [1]
查看完整版本: python3多线程趣味详解