Python多线程threading和multiprocessing模块实例解析


Posted in Python onJanuary 29, 2018

本文研究的主要是Python多线程threading和multiprocessing模块的相关内容,具体介绍如下。

线程是一个进程的实体,是由表示程序运行状态的寄存器(如程序计数器、栈指针)以及堆栈组成,它是比进程更小的单位。
线程是程序中的一个执行流。一个执行流是由CPU运行程序代码并操作程序的数据所形成的。因此,线程被认为是以CPU为主体的行为。

线程不包含进程地址空间中的代码和数据,线程是计算过程在某一时刻的状态。所以,系统在产生一个线程或各个线程之间切换时,负担要比进程小得多。

线程是一个用户级的实体,线程结构驻留在用户空间中,能够被普通的用户级函数直接访问。

一个线程本身不是程序,它必须运行于一个程序(进程)之中。因此,线程可以定义为一个程序中的单个执行流。

多线程是指一个程序中包含多个执行流,多线程是实现并发的一种有效手段。一个进程在其执行过程中,可以产生多个线程,形成多个执行流。每个执行流即每个线程也有它自身的产生、存在和消亡的过程。

多线程程序设计的含义就是可以将程序任务分成几个并行的子任务。

线程的状态图:

Python多线程threading和multiprocessing模块实例解析

Python中常使用的线程模块

  • thread(低版本使用的),threading
  • Queue
  • multiprocessing

threading

thread模块是Python低版本中使用的,高版本中被threading代替了。threading模块提供了更方便的API来操作线程。

threading.Thread

Thread是threading模块中最重要的类之一,可以使用它来创建线程。创建新的线程有两种方法:

  • 方法一:直接创建threading.Thread类的对象,初始化时将可调用对象作为参数传入。
  • 方法二:通过继承Thread类,重写它的run方法。

Thread类的构造方法:

__init__(group=None, target=None, name=None, args=(), kwargs=None, verbose=None)

参数说明:

group:线程组,目前还没有实现,库引用中提示必须是None。
target:要执行的方法;
name:线程名;
args/kwargs:要传入方法的参数。

Thread类拥有的实例方法:

isAlive():返回线程是否在运行。正在运行指的是启动后,终止前。

getName(name)/setName(name):获取/设置线程名。

isDaemon(bool)/setDaemon(bool):获取/设置是否为守护线程。初始值从创建该线程的线程继承而来,当没有非守护线程仍在运行时,程序将终止。

start():启动线程。

join([timeout]):阻塞当前上下文环境的线程,直到调用此方法的线程终止或到达指定的等待时间timeout(可选参数)。即当前的线程要等调用join()这个方法的线程执行完,或者是达到规定的时间。

直接创建threading.Thread类的对象

实例:

from threading import Thread
import time
def run(a = None, b = None) :
 print a, b 
 time.sleep(1)

t = Thread(target = run, args = ("this is a", "thread"))
#此时线程是新建状态

print t.getName()#获得线程对象名称
print t.isAlive()#判断线程是否还活着。
t.start()#启动线程
t.join()#等待其他线程运行结束

执行结果:

Thread-1
False
this is a thread

注意:

t = Thread(target = run, args = ("this is a", "thread"))

这句只是创建了一个线程,并未执行这个线程,此时线程处于新建状态。

t.start()#启动线程

启动线程,此时线程扔为运行,只是处于准备状态。

自定义函数run(),使我们自己根据我们需求自己定义的,函数名可以随便取,run函数的参数来源于后面的args元组。

通过继承Thread类

实例:

from threading import Thread
import time

class MyThread(Thread) :
 def __init__(self, a) :
  super(MyThread, self).__init__()
  #调用父类的构造方法
  self.a = a

 def run(self) :
  print "sleep :", self.a
  time.sleep(self.a)

t1 = MyThread(2)
t2 = MyThread(4)
t1.start()
t2.start()
t1.join()
t2.join()

执行结果:

Python多线程threading和multiprocessing模块实例解析

由于创建了两个并发执行的线程t1和t2,并发线程的执行时间不定,谁先执行完的时间也不定,所以执行后打印的结果顺序也是不定的。每一次执行都有可能出现不同的结果。

注意:

继承Thread类的新类MyThread构造函数中必须要调用父类的构造方法,这样才能产生父类的构造函数中的参数,才能产生线程所需要的参数。新的类中如果需要别的参数,直接在其构造方法中加即可。

同时,新类中,在重写父类的run方法时,它默认是不带参数的,如果需要给它提供参数,需要在类的构造函数中指定,因为在线程执行的过程中,run方法时线程自己去调用的,不用我们手动调用,所以没法直接给传递参数,只能在构造方法中设定好参数,然后再run方法中调用。

针对join()函数用法的实例:

# encoding: UTF-8
import threading
import time

def context(tJoin):
  print 'in threadContext.'
  tJoin.start()
  # 将阻塞tContext直到threadJoin终止。
  tJoin.join()
  # tJoin终止后继续执行。
  print 'out threadContext.'

def join():
  print 'in threadJoin.'
  time.sleep(1)
  print 'out threadJoin.'

tJoin = threading.Thread(target=join)
tContext = threading.Thread(target=context, args=(tJoin,))
tContext.start()

执行结果:

in threadContext.
in threadJoin.
out threadJoin.
out threadContext.

解析:

主程序中这句tJoin = threading.Thread(target=join)执行后,只是创建了一个线程对象tJoin,但并未启动该线程。

tContext = threading.Thread(target=context, args=(tJoin,))
tContext.start()

上面这两句执行后,创建了另一个线程对象tContext并启动该线程(打印in threadContext.),同时将tJoin线程对象作为参数传给context函数,在context函数中,启动了tJoin这个线程,同时该线程又调用了join()函数(tJoin.join()),那tContext线程将等待tJoin这线程执行完成后,才能继续tContext线程后面的,所以先执行join()函数,打印输出下面两句:

in threadJoin.
out threadJoin.

tJoin线程执行结束后,继续执行tContext线程,于是打印输出了out threadContext.,于是就看到我们上面看到的输出结果,并且无论执行多少次,结果都是这个顺序。但如果将context()函数中tJoin.join()这句注释掉,再执行该程序,打印输出的结果顺序就不定了,因为此时这两线程就是并发执行的。

multiprocessing.dummy

Python中线程multiprocessing模块与进程使用的同一模块。使用方法也基本相同,唯一不同的是,from multiprocessing import Pool这样导入的Pool表示的是进程池;
from multiprocessing.dummy import Pool这样导入的Pool表示的是线程池。这样就可以实现线程里面的并发了。

线程池实例:

import time
from multiprocessing.dummy import Pool as ThreadPool
#给线程池取一个别名ThreadPool
def run(fn):
 time.sleep(2)
 print fn

if __name__ == '__main__':
 testFL = [1,2,3,4,5]
 pool = ThreadPool(10)#创建10个容量的线程池并发执行
 pool.map(run, testFL)
 pool.close()
 pool.join()

执行结果:

Python多线程threading和multiprocessing模块实例解析

这里的pool.map()函数,跟进程池的map函数用法一样,也跟内建的map函数一样。

总结

以上就是本文关于Python多线程threading和multiprocessing模块实例解析的全部内容,希望对大家有所帮助。感兴趣的朋友可以继续参阅本站其他相关专题,如有不足之处,欢迎留言指出。感谢朋友们对本站的支持!

Python 相关文章推荐
Python中集合的内建函数和内建方法学习教程
Aug 19 Python
Python中操作mysql的pymysql模块详解
Sep 13 Python
python自动化测试之如何解析excel文件
Jun 27 Python
Mac在python3环境下安装virtualwrapper遇到的问题及解决方法
Jul 09 Python
django的ORM操作 删除和编辑实现详解
Jul 24 Python
关于Keras模型可视化教程及关键问题的解决
Jan 24 Python
keras 指定程序在某块卡上训练实例
Jun 22 Python
Django实现内容缓存实例方法
Jun 30 Python
Python中使用Lambda函数的5种用法
Apr 01 Python
Python集合set()使用的方法详解
Mar 18 Python
Python字符串常规操作小结
Apr 03 Python
Python中re模块的元字符使用小结
Apr 07 Python
Python编程scoketServer实现多线程同步实例代码
Jan 29 #Python
Python模块搜索路径代码详解
Jan 29 #Python
python机器人行走步数问题的解决
Jan 29 #Python
python的socket编程入门
Jan 29 #Python
Python 错误和异常代码详解
Jan 29 #Python
python实现机器人行走效果
Jan 29 #Python
浅谈Python用QQ邮箱发送邮件时授权码的问题
Jan 29 #Python
You might like
当年上海收录机产品生产,进口和价格情况
2021/03/04 无线电
Zend Guard一些常见问题解答
2008/09/11 PHP
thinkphp浏览历史功能实现方法
2014/10/29 PHP
php编写简单的文章发布程序
2015/06/18 PHP
PHP利用Cookie设置用户30分钟未操作自动退出功能
2017/07/03 PHP
tp5框架前台无限极导航菜单类实现方法分析
2020/03/29 PHP
php设计模式之适配器模式实例分析【星际争霸游戏案例】
2020/04/07 PHP
PHP基于phpqrcode类生成二维码的方法示例详解
2020/08/07 PHP
网站导致浏览器崩溃的原因总结(多款浏览器) 推荐
2010/04/15 Javascript
JavaScript如何从listbox里同时删除多个项目
2013/10/12 Javascript
jQuery获取及设置表单input各种类型值的方法小结
2016/05/24 Javascript
JS 根据子网掩码,网关计算出所有IP地址范围示例
2020/04/23 Javascript
JavaScript实现左右下拉框动态增删示例
2017/03/09 Javascript
JS使用正则表达式找出最长连续子串长度
2017/10/26 Javascript
使用命令行工具npm新创建一个vue项目的方法
2017/12/27 Javascript
vue-cli脚手架引入弹出层layer插件的几种方法
2019/06/24 Javascript
微信小程序事件 bindtap bindinput代码实例
2019/08/26 Javascript
layui加载数据显示loading加载完成loading消失的实例代码
2019/09/23 Javascript
Vue退出登录时清空缓存的实现
2019/11/12 Javascript
javascript实现倒计时效果
2020/02/17 Javascript
JS使用正则表达式实现常用的表单验证功能分析
2020/04/30 Javascript
详解ES6中class的实现原理
2020/10/03 Javascript
JS相册图片抖动放大展示效果的示例代码
2021/01/29 Javascript
[01:20]2018DOTA2亚洲邀请赛总决赛战队LGD晋级之路
2018/04/07 DOTA
简单的Python抓taobao图片爬虫
2014/10/26 Python
Python编程中实现迭代器的一些技巧小结
2016/06/21 Python
Python实现信用卡系统(支持购物、转账、存取钱)
2016/06/24 Python
Pyqt5 基本界面组件之inputDialog的使用
2019/06/25 Python
python-tornado的接口用swagger进行包装的实例
2019/08/29 Python
什么是Connection-oriented Protocol/Connectionless Protocol面向连接的协议/无连接协议
2012/09/06 面试题
安全技术说明书
2014/05/09 职场文书
治庸问责心得体会
2014/09/12 职场文书
2014年组织部工作总结
2014/11/14 职场文书
2014年驻村干部工作总结
2014/11/17 职场文书
2014年机关工会工作总结
2014/12/19 职场文书
大学生求职自荐信范文
2015/03/04 职场文书