前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >python3多线程趣味详解

python3多线程趣味详解

作者头像
机器学习和大数据挖掘
发布2019-07-02 10:49:29
7640
发布2019-07-02 10:49:29
举报
文章被收录于专栏:数据挖掘数据挖掘数据挖掘

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

记录来的完成时间为:

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

但是直接就结束了?

完成的时间为:0.0010008811950683594

原来是setDaemon,主线程启动两个子线程后做事后,主线程就不管子线程是否运行完毕,直接往下运行,直接运行到

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

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

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

运行结果也是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 = 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[i]))
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))

程序运行的时间是:

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

运行时间为:

完成的时间为: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首歌是:music2
19 吃完了一包零食
20 我正在听着歌吃辣条零食
21 吃完了一包零食
22 零食线程结束了##################
23 切换下一首歌...
24 第3首歌是:music3
25 切换下一首歌...
26 听歌线程结束了##################

perfect!

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2016-09-06 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档