51Testing软件测试论坛
标题:
python3多线程趣味详解
[打印本页]
作者:
小小糖
时间:
2018-4-23 13:50
标题:
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))
复制代码
复制代码
记录来的完成时间为:
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[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))
复制代码
复制代码
但是直接就结束了?
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[i]))
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[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))
复制代码
作者:
小小糖
时间:
2018-4-23 13:51
复制代码
运行结果也是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 听歌线程结束了##################
作者:
梦想家
时间:
2018-5-9 10:00
欢迎光临 51Testing软件测试论坛 (http://bbs.51testing.com/)
Powered by Discuz! X3.2