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 相关文章推荐
wxPython定时器wx.Timer简单应用实例
Jun 03 Python
Python文件右键找不到IDLE打开项解决办法
Jun 08 Python
python计算圆周率pi的方法
Jul 11 Python
Python求出0~100以内的所有素数
Jan 23 Python
Python cookbook(数据结构与算法)字典相关计算问题示例
Feb 18 Python
Django Web开发中django-debug-toolbar的配置以及使用
May 06 Python
Python爬虫包BeautifulSoup实例(三)
Jun 17 Python
python实现扫描局域网指定网段ip的方法
Apr 16 Python
Django用户认证系统 组与权限解析
Aug 02 Python
Python3中configparser模块读写ini文件并解析配置的用法详解
Feb 18 Python
PYcharm 激活方法(推荐)
Mar 23 Python
jupyter实现重新加载模块
Apr 16 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
MOTOROLA 摩托罗拉 MODEL 66-XI五灯中波收音机
2021/03/02 无线电
中英文字符串翻转函数
2008/12/09 PHP
PHP正则表达式之定界符和原子介绍
2012/10/05 PHP
PHP网页游戏学习之Xnova(ogame)源码解读(十六)
2014/06/30 PHP
php常用数组array函数实例总结【赋值,拆分,合并,计算,添加,删除,查询,判断,排序】
2016/12/07 PHP
PHP常见过waf webshell以及最简单的检测方法
2019/05/21 PHP
Yii2框架视图(View)操作及Layout的使用方法分析
2019/05/27 PHP
学习ExtJS 访问容器对象
2009/10/07 Javascript
javascript截图 jQuery插件imgAreaSelect使用详解
2016/05/04 Javascript
Vue指令v-for遍历输出JavaScript数组及json对象的常见方式小结
2019/02/11 Javascript
js实现web调用摄像头 js截取视频画面
2019/04/21 Javascript
node学习笔记之读写文件与开启第一个web服务器操作示例
2019/05/29 Javascript
vue 中url 链接左边的小图标更改问题
2019/12/30 Javascript
详解JavaScript之Array.reduce源码解读
2020/11/01 Javascript
如何在 Vue 表单中处理图片
2021/01/26 Vue.js
python中子类调用父类函数的方法示例
2017/08/18 Python
利用 python 对目录下的文件进行过滤删除
2017/12/27 Python
快速了解Python中的装饰器
2018/01/11 Python
使用Python实现windows下的抓包与解析
2018/01/15 Python
Python实现的爬取百度文库功能示例
2019/02/16 Python
Python OS模块实例详解
2019/04/15 Python
简单了解Python3里的一些新特性
2019/07/13 Python
使用python模拟命令行终端的示例
2019/08/13 Python
python实现打砖块游戏
2020/02/25 Python
python实现从ftp服务器下载文件
2020/03/03 Python
Python数据可视化实现多种图例代码详解
2020/07/14 Python
python通过函数名调用函数的几种场景
2020/09/23 Python
巴西电子、家电、智能手机购物网站:Girafa
2019/06/04 全球购物
2014年销售经理工作总结
2014/12/01 职场文书
银行资信证明
2015/06/17 职场文书
欠条格式范本
2015/07/03 职场文书
幼儿园教师教育随笔
2015/08/14 职场文书
学习杨善洲同志先进事迹心得体会
2016/01/23 职场文书
《大禹治水》教学反思
2016/02/22 职场文书
MySQL 亿级数据导入导出及迁移笔记
2021/06/18 MySQL
使用Java去实现超市会员管理系统
2022/03/18 Java/Android