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之时间模块详述 ...
随机推荐
- iOS System Services
System Services is a singleton class to gather all available information about a device. Over 75 met ...
- Android RecyclerView(瀑布流)水平/垂直方向分割线
Android RecyclerView(瀑布流)水平/垂直方向分割线 Android RecyclerView不像过去的ListView那样随意的设置水平方向的分割线,如果要实现Recycle ...
- 拆解一个简单的KeyFile保护
系统 : Windows xp 程序 : abexcrackme3 程序下载地址 :http://pan.baidu.com/s/1mh3TiqO 要求 : 伪造Keyfile 使用工具 :IDA 可 ...
- Unity3D ShaderLab 使用alpha参数创建透明效果
Unity3D ShaderLab 使用alpha参数创建透明效果 其实Unity为了方便我们的工作,为我们内置了很多参数.比如马上用到的透明功能. 准备场景新建Shader Material ,一张 ...
- 30道四则运算<2>
#include<iostream> #include<time.h> #include<fstream> #define random() (rand()%100 ...
- I.MX6 Android 5.1 快速合成系统
/**************************************************************************** * I.MX6 Android 5.1 快速 ...
- 《more effective C++》条款10 防止构造函数里的资源泄露
构造函数也可能发生内存泄露,考虑如下程序: class A { public: A(int *p) { if(p!=NULL) num=p; ); //do something } private: ...
- 【题解】【BT】【Leetcode】Binary Tree Preorder/Inorder/Postorder (Iterative Solution)
[Inorder Traversal] Given a binary tree, return the inorder traversal of its nodes' values. For exam ...
- 读metronic文档学到的几个知识点
1.RTL 同样的页面,它做了两套.为什么,因为在这个世界上,有些民族,有些语种,是从右向左来的. 2. google material design 同样的一套东西,又分别做了google mat ...
- Nginx 的线程池与性能剖析
http://blog.yemou.net/article/query/info/tytfjhfascvhzxcyt158 正如我们所知,NGINX采用了异步.事件驱动的方法来处理连接.这种处理方 ...