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多线程趣味详解的更多相关文章

  1. python3多线程应用详解(第四卷:图解多线程中LOCK)

    先来看下图形对比: 发现没有这种密集型计算的任务中,多线程没有穿行的速率快,原因就是多线程在线程切换间也是要耗时的而密集型计算任务执行时几乎没以偶IO阻塞,这样你说谁快

  2. python3多线程应用详解(第二卷:多线程到底是怎么工作的)

    现在很多人都说用多线程工作快是因为多个不同任务可以同时执行,注意我说的是不同任务,要是重复做一件事达到相同效果就是画蛇添足了,其实这是个错误的说法,线程真正的本质是无法同时执行的.现在我们来看下多线程 ...

  3. python3多线程应用详解(第三卷:图解多线程中join,守护线程应用)

  4. python3多线程应用详解(第一卷:线程的本质概念)

    之前我用过多线程的方式执行了爬虫程序,爬取了糗事百科的数据可以看到速率非常之快,就像正常一个人他要完一个汉堡,再吃喝一瓶水才能走,结果他边吃汉堡边喝水,速率一下加快了一样.首先我们看看什么是线程: 图 ...

  5. .NET多线程同步方法详解

    .NET多线程同步方法详解(一):自由锁(InterLocked) .NET多线程同步方法详解(二):互斥锁(lock) NET多线程同步方法详解(三):读写锁(ReadWriteLock) .NET ...

  6. 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出来了,如果想使用最新版本,赶紧升级下 ...

  7. Java多线程——多线程方法详解

    本系列文章是Java多线程的详解介绍,对多线程还不熟悉的同学可以先去看一下我的这篇博客Java基础系列3:多线程超详细总结,这篇博客从宏观层面介绍了多线程的整体概况,接下来的几篇文章是对多线程的深入剖 ...

  8. Swift - 多线程GCD详解

    //  GCD详解 //  目录: //  1. 创建GCD队列(最常用) //  2. 自定义创建队列 //  3. 使用多线程实现延迟加载 //  4. 使用多线程实现重复(循环) //  5. ...

  9. python3 常用模块详解

    这里是python3的一些常用模块的用法详解,大家可以在这里找到它们. Python3 循环语句 python中模块sys与os的一些常用方法 Python3字符串 详解 Python3之时间模块详述 ...

随机推荐

  1. Qt 中使用vector

    新建Empty qmake project,包含如下两个文件: .pro文件 SOURCES += \ main.cpp QT += core CONFIG += c++11 // 支持C++11 . ...

  2. ViewBag、ViewData和TempData的使用和区别

    在MVC3开始,视图数据可以通过ViewBag属性访问,在MVC2中则是使用ViewData. MVC3中保留了ViewData的使用. ViewBag 是动态类型(dynamic),ViewData ...

  3. 4 Values whose Sum is 0_upper_bound&&ower_bound

    Description The SUM problem can be formulated as follows: given four lists A, B, C, D of integer val ...

  4. Inno Setup 安装前卸载原程序

    Inno Setup 安装前卸载原程序 分类: Install Setup 2013-02-02 15:53 2315人阅读 评论(0) 收藏 举报 很多時候我們需要在安裝文件之前卸載原有的程序而不是 ...

  5. javascript js写特效日历

    <!doctype html public "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  6. iOS-代理

    1.协议是一组通讯协议,一般用作两个类之间的通信. 2.协议声明了一组所有类对象都可以实现的接口. 3.协议不是类,用@protocol关键字声明一个协议. 4.与协议有关的两个对象,代理者和委托者. ...

  7. usb serial for android

    /******************************************************************** * usb serial for android * 说明: ...

  8. Python 结巴分词

    今天的任务是对txt文本进行分词,有幸了解到"结巴"中文分词,其愿景是做最好的Python中文分词组件.有兴趣的朋友请点这里. jieba支持三种分词模式: *精确模式,试图将句子 ...

  9. UVA 11997 STL 优先队列

    题目链接: http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem ...

  10. leetcode 122. Best Time to Buy and Sell Stock II ----- java

    Say you have an array for which the ith element is the price of a given stock on day i. Design an al ...