python3多线程趣味详解
python3的多线程很多人无法理解是怎么运行的,因此本文从程序猿的日常生活出发,写了一个由浅入深的多线程教程,这样子大家就不会觉得陌生了,多线程真的很简单很简单!
不要讲多线程局限于库或者框架,自己造轮子才是最大的快乐。
-----------------------------------------以下是正文--------------------------------------------
假设我是一个程序猿,我想听歌,但是我又要打码,所以有:
我听完歌就去打码:
#!/usr/bin/python3.4
# -*- coding: utf-8 -*- import time def matter1(music):
print("我想听这些歌") for i in range(0,len(music)):
print("第" + str(i + 1) + "首歌是:" + str(music[i]))
# 当前时间为
print(time.strftime('%Y%H%M%S', time.localtime()))
# 假设每一首歌曲的时间是2秒
time.sleep(2)
print("切换下一首歌...") def matter2(number):
print("我在打码") j = 0
while j <= number:
print("我准备写入第" + str(j + 1) +"行代码")
j = j + 1
# 当前时间为
print(time.strftime('%Y%H%M%S', time.localtime()))
# 假设每写一行代码的时间为1秒
time.sleep(1)
print("写下一行代码...") if __name__ == '__main__': start = time.time() # 设定我要听的歌为
music = ["music1","music2","music3"]
# 开始听歌
matter1(music)
# 设定我要打码的行数
number = 5
# 开始打码
matter2(number) end = time.time()
print("完成的时间为:" + str(end - start))
记录来的完成时间为:
完成的时间为:12.007483959197998
时间上完全符合,但是身为一个程序猿,可以一边打码一边听歌,那么设计一个多线程,让他们同时进行:
#!/usr/bin/python3.4
# -*- coding: utf-8 -*- import time
import threading def matter1(music):
print("我想听这些歌") for i in range(0,len(music)):
print("第" + str(i + 1) + "首歌是:" + str(music[i]))
# 当前时间为
print(time.strftime('%Y%H%M%S', time.localtime()))
# 假设每一首歌曲的时间是2秒
time.sleep(2)
print("切换下一首歌...") def matter2(number):
print("我在打码") j = 0
while j <= number:
print("我准备写入第" + str(j + 1) +"行代码")
j = j + 1
# 当前时间为
print(time.strftime('%Y%H%M%S', time.localtime()))
# 假设每写一行代码的时间为1秒
time.sleep(1)
print("写下一行代码...") if __name__ == '__main__':
# 设定我要听的歌为
music = ["music1","music2","music3"] # 设定我要打码的行数
number = 5
# 建立一个新数组
threads = []
# 将听歌放入数组里面
thing1 = threading.Thread(target=matter1, args=(music,))
threads.append(thing1)
# 将打码放入数组里面
thing2 = threading.Thread(target=matter2, args=(number,))
threads.append(thing2) # 开始时间
start = time.time()
# 写个for让两件事情都进行
for thing in threads:
# setDaemon为主线程启动了线程matter1和matter2
# 启动也就是相当于执行了这个for循环
thing.setDaemon(True)
thing.start() # 结束时间
end = time.time()
print("完成的时间为:" + str(end - start))
但是直接就结束了?
完成的时间为:0.0010008811950683594
原来是setDaemon,主线程启动两个子线程后做事后,主线程就不管子线程是否运行完毕,直接往下运行,直接运行到
print("完成的时间为:" + str(end - start))
然后程序就结束了,因此,为了防止子线程还没结束主线程就结束的意外情况,在程序里面加个join:
import time
import threading def matter1(music):
print("我想听这些歌") for i in range(0,len(music)):
print("第" + str(i + 1) + "首歌是:" + str(music[i]))
# 当前时间为
print(time.strftime('%Y%H%M%S', time.localtime()))
# 假设每一首歌曲的时间是2秒
time.sleep(2)
print("切换下一首歌...") def matter2(number):
print("我在打码") j = 0
while j <= number:
print("我准备写入第" + str(j + 1) +"行代码")
j = j + 1
# 当前时间为
print(time.strftime('%Y%H%M%S', time.localtime()))
# 假设每写一行代码的时间为1秒
time.sleep(1)
print("写下一行代码...") if __name__ == '__main__':
# 设定我要听的歌为
music = ["music1","music2","music3"] # 设定我要打码的行数
number = 5
# 建立一个新数组
threads = []
# 将听歌放入数组里面
thing1 = threading.Thread(target=matter1, args=(music,))
threads.append(thing1)
# 将打码放入数组里面
thing2 = threading.Thread(target=matter2, args=(number,))
threads.append(thing2) # 开始时间
start = time.time()
# 写个for让两件事情都进行
for thing in threads:
# setDaemon为主线程启动了线程matter1和matter2
# 启动也就是相当于执行了这个for循环
thing.setDaemon(True)
thing.start() # 子线程没结束前主线程会被卡在这里
thing1.join()
thing2.join()
# 结束时间
end = time.time()
print("完成的时间为:" + str(end - start))
最后运行的时间就是打码的时间:
完成的时间为:6.003339052200317
这就真正做到了一边听歌一边打码的双手互博的状态,本文后面的那0.003333秒就别纠结了,系统运行程序花个0.0033333秒不过分吧
偷懒打码打4行:
number = 4
完成的时间为:5.008083820343018
------------------------------我是快乐的分割线------------------------------
网上的多线程都是写成“类”的形式,这里写成函数不符合“大众”标准,那么就改成类的形式:
#!/usr/bin/python3.4
# -*- coding: utf-8 -*- import time
import threading class MyThread(threading.Thread):
def __init__(self, func, args, name=''):
threading.Thread.__init__(self)
self.name = name
self.func = func
self.args = args
#self.counter = counter def run(self):
# 某某线程要开始了
print(self.name + "开始了##################") if self.name == "听歌线程":
matter1(music)
elif self.name == "打码线程":
matter2(number)
print(self.name + "结束了##################") def matter1(music):
for i in range(0,len(music)):
print("第" + str(i + 1) + "首歌是:" + str(music[i]))
# 假设每一首歌曲的时间是2秒
time.sleep(2)
print("切换下一首歌...") def matter2(number):
j = 0
while j <= number:
print("我准备写入第" + str(j + 1) +"行代码")
j = j + 1
# 假设每写一行代码的时间为1秒
time.sleep(1)
print("写下一行代码...") if __name__ == '__main__':
# 设定我要听的歌为
music = ["music1","music2","music3"] # 设定我要打码的行数
number = 4 # 开始时间
start = time.time() thing1 = MyThread(matter1, music,"听歌线程")
thing2 = MyThread(matter2, number, "打码线程")
thing1.start()
thing2.start()
thing1.join()
thing2.join() # 结束时间
end = time.time()
print("完成的时间为:" + str(end - start))
运行结果也是6秒:
完成的时间为:6.001942157745361
----------------------我是快乐的分割线-------------------------
程序猿在跑代码的时候是很无聊的,无聊的时候就会想到去吃零食,那么我就加入一个函数:
#!/usr/bin/python3.4
# -*- coding: utf-8 -*- import time
import threading class MyThread(threading.Thread):
def __init__(self, func, args, name=''):
threading.Thread.__init__(self)
self.name = name
self.func = func
self.args = args
#self.counter = counter def run(self):
# 某某线程要开始了
print(self.name + "开始了##################") if self.name == "听歌线程":
matter1(music)
elif self.name == "打码线程":
matter2(number)
elif self.name == "零食线程":
matter3(snacks)
print(self.name + "结束了##################") def matter1(music):
for i in range(0,len(music)):
print("第" + str(i + 1) + "首歌是:" + str(music[i]))
# 假设每一首歌曲的时间是2秒
time.sleep(2)
print("切换下一首歌...") def matter2(number):
j = 0
while j <= number:
print("我准备写入第" + str(j + 1) +"行代码")
j = j + 1
# 假设每写一行代码的时间为1秒
time.sleep(1)
print("写下一行代码...") def matter3(snacks):
for k in range(0,len(snacks)):
print("我正在听着歌吃" + str(snacks[k]) + "零食")
#每吃一袋零食间隔5秒
time.sleep(5)
print("吃完了一包零食") if __name__ == '__main__':
# 设定我要听的歌为
music = ["music1","music2","music3"] # 设定我要打码的行数
number = 4 # 设定我想吃的零食
snacks = ["咪咪","辣条"] # 开始时间
start = time.time() thing1 = MyThread(matter1, music,"听歌线程")
thing2 = MyThread(matter2, number, "打码线程")
thing3 = MyThread(matter3, snacks, "零食线程")
thing1.start()
thing2.start()
thing3.start()
thing1.join()
thing2.join()
thing3.join() # 结束时间
end = time.time()
print("完成的时间为:" + str(end - start))
程序运行的时间是:
完成的时间为:10.000968933105469
感觉还是吃零食比较耗时间。但是但是,程序猿只有两个手,那么吃零食和打码是不能同时进行了,那么这里加个线程锁:
#!/usr/bin/python3.4
# -*- coding: utf-8 -*- import time
import threading # 打开线程锁
lock = threading.Lock() class MyThread(threading.Thread):
def __init__(self, func, args, name=''):
threading.Thread.__init__(self)
self.name = name
self.func = func
self.args = args
#self.counter = counter def run(self):
# 某某线程要开始了
print(self.name + "开始了##################") if self.name == "听歌线程":
matter1(music)
elif self.name == "打码线程":
matter2(number)
elif self.name == "零食线程":
matter3(snacks)
print(self.name + "结束了##################") def matter1(music):
for i in range(0,len(music)):
print("第" + str(i + 1) + "首歌是:" + str(music[i]))
# 假设每一首歌曲的时间是2秒
time.sleep(2)
print("切换下一首歌...") def matter2(number):
lock.acquire()
j = 0
while j <= number:
print("我准备写入第" + str(j + 1) +"行代码")
j = j + 1
# 假设每写一行代码的时间为1秒
time.sleep(1)
print("写下一行代码...")
lock.release() def matter3(snacks):
lock.acquire()
for k in range(0,len(snacks)):
print("我正在听着歌吃" + str(snacks[k]) + "零食")
#每吃一袋零食间隔5秒
time.sleep(5)
print("吃完了一包零食")
lock.release() if __name__ == '__main__':
# 设定我要听的歌为
music = ["music1","music2","music3"] # 设定我要打码的行数
number = 4 # 设定我想吃的零食
snacks = ["咪咪","辣条"] # 开始时间
start = time.time() thing1 = MyThread(matter1, music,"听歌线程")
thing2 = MyThread(matter2, number, "打码线程")
thing3 = MyThread(matter3, snacks, "零食线程")
thing1.start()
thing2.start()
thing3.start()
thing1.join()
thing2.join()
thing3.join() # 结束时间
end = time.time()
print("完成的时间为:" + str(end - start))
运行时间为:
完成的时间为:15.001857995986938
这里解释一下:
只是听歌和打码花的时间是5s多; 听歌、打码、吃零食同时进行是10s多;
加了线程锁后,打码和吃零食不能同时进行,那么就变成:
听歌和打码花的时间是5s多; 单独吃零食是10s多,加起来就是15秒;
为了验证吃零食的时候还是听着歌的,所以将听歌的时间间隔改成10s,得到的运行时间为:
完成的时间为:30.000711917877197
运行结果贴出来看一下:
听歌线程开始了##################
第1首歌是:music1
打码线程开始了##################
我准备写入第1行代码
零食线程开始了##################
写下一行代码...
我准备写入第2行代码
写下一行代码...
我准备写入第3行代码
写下一行代码...
我准备写入第4行代码
写下一行代码...
我准备写入第5行代码
写下一行代码...
打码线程结束了##################
我正在听着歌吃咪咪零食
切换下一首歌...
第2首歌是:music2
吃完了一包零食
我正在听着歌吃辣条零食
吃完了一包零食
零食线程结束了##################
切换下一首歌...
第3首歌是:music3
切换下一首歌...
听歌线程结束了##################
perfect!
python3多线程趣味详解的更多相关文章
- python3多线程应用详解(第四卷:图解多线程中LOCK)
先来看下图形对比: 发现没有这种密集型计算的任务中,多线程没有穿行的速率快,原因就是多线程在线程切换间也是要耗时的而密集型计算任务执行时几乎没以偶IO阻塞,这样你说谁快
- python3多线程应用详解(第二卷:多线程到底是怎么工作的)
现在很多人都说用多线程工作快是因为多个不同任务可以同时执行,注意我说的是不同任务,要是重复做一件事达到相同效果就是画蛇添足了,其实这是个错误的说法,线程真正的本质是无法同时执行的.现在我们来看下多线程 ...
- python3多线程应用详解(第三卷:图解多线程中join,守护线程应用)
- python3多线程应用详解(第一卷:线程的本质概念)
之前我用过多线程的方式执行了爬虫程序,爬取了糗事百科的数据可以看到速率非常之快,就像正常一个人他要完一个汉堡,再吃喝一瓶水才能走,结果他边吃汉堡边喝水,速率一下加快了一样.首先我们看看什么是线程: 图 ...
- .NET多线程同步方法详解
.NET多线程同步方法详解(一):自由锁(InterLocked) .NET多线程同步方法详解(二):互斥锁(lock) NET多线程同步方法详解(三):读写锁(ReadWriteLock) .NET ...
- Mac OS X10.9安装的Python2.7升级Python3.4步骤详解
Mac OS X10.9安装的Python2.7升级Python3.4步骤详解 Mac OS X10.9默认带了Python2.7,不过现在Python3.4.0出来了,如果想使用最新版本,赶紧升级下 ...
- Java多线程——多线程方法详解
本系列文章是Java多线程的详解介绍,对多线程还不熟悉的同学可以先去看一下我的这篇博客Java基础系列3:多线程超详细总结,这篇博客从宏观层面介绍了多线程的整体概况,接下来的几篇文章是对多线程的深入剖 ...
- Swift - 多线程GCD详解
// GCD详解 // 目录: // 1. 创建GCD队列(最常用) // 2. 自定义创建队列 // 3. 使用多线程实现延迟加载 // 4. 使用多线程实现重复(循环) // 5. ...
- python3 常用模块详解
这里是python3的一些常用模块的用法详解,大家可以在这里找到它们. Python3 循环语句 python中模块sys与os的一些常用方法 Python3字符串 详解 Python3之时间模块详述 ...
随机推荐
- linux 下安装rsync
一.服务器端配置: 1.安装xinetd,并修改rsync相关配置 # yum -y install xinetd # vi /etc/xinetd.d/rsync 如下代码: service rsy ...
- Unity3D ShaderLab压缩混合纹理贴图
Unity3D ShaderLab压缩混合纹理贴图 纹理可以用于存储大量的数据,我们可以把多个图像打包存储在单一的RGBA纹理上,然后通过着色器代码提取这些元素, 我们就可以使用每个图片的RGBA通道 ...
- Quirks模式是什么?
什么是DOCTYPE: DOCTYPE,或者称为 Document Type Declaration(文档类型声明,缩写 DTD).通常情况下,DOCTYPE 位于一个 HTML 文档的最前面的 位置 ...
- yii弹出层
Yii弹出层,包装了JQuery的JDialog,使用很方便.Yii组件功能太强大,强大到无法自拔 $this->beginWidget('zii.widgets.jui.CJuiDialog' ...
- USB Packet Types
USB has four different packet types. Token packets indicate the type of transaction to follow, data ...
- springmvc学习笔记---面向移动端支持REST API
前言: springmvc对注解的支持非常灵活和飘逸, 也得web编程少了以往很大一坨配置项. 另一方面移动互联网的到来, 使得REST API变得流行, 甚至成为主流. 因此我们来关注下spring ...
- memcache 线程深入理解分析 及 源码研究
http://blog.csdn.net/huithe/article/details/8006186
- hdu1712 ACboy needs your help 分组背包
最基础的分组背包~ #include <iostream> #include <cstdio> #include <cstdlib> #include <cs ...
- Codeforces Round #127 (Div. 2)
A. LLPS 长度最大10,暴力枚举即可. B. Brand New Easy Problem 枚举\(n\)的全排列,按题意求最小的\(x\),即逆序对个数. C. Clear Symmetry ...
- scala言语基础学习十
类型参数 泛型函数 多个参数 使用泛型参数时候,不给类型scala也能自己判断 上边界bounds 下边界bounds 专门用于打包泛型数组