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

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

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

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

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

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

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

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

线程的状态图:

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()

执行结果:

由于创建了两个并发执行的线程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()

执行结果:

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

总结

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

您可能感兴趣的文章:

  • Python线程创建和终止实例代码
  • Python实现可设置持续运行时间、线程数及时间间隔的多线程异步post请求功能
  • Python基于ThreadingTCPServer创建多线程代理的方法示例
  • Python之多线程爬虫抓取网页图片的示例代码
  • Python3多线程爬虫实例讲解代码
  • python回调函数中使用多线程的方法
  • Python多线程爬虫实战_爬取糗事百科段子的实例
  • python编程测试电脑开启最大线程数实例代码
(0)

相关推荐

  • Python3多线程爬虫实例讲解代码

    多线程概述 多线程使得程序内部可以分出多个线程来做多件事情,充分利用CPU空闲时间,提升处理效率.python提供了两个模块来实现多线程thread 和threading ,thread 有一些缺点,在threading 得到了弥补.并且在Python3中废弃了thread模块,保留了更强大的threading模块. 使用场景 在python的原始解释器CPython中存在着GIL(Global Interpreter Lock,全局解释器锁),因此在解释执行python代码时,会产生互斥锁来限

  • python编程测试电脑开启最大线程数实例代码

    本文实例代码主要实现python编程测试电脑开启最大线程数,具体实现代码如下. #!/usr/bin/env python #coding=gbk import threading import time, random, sys class Counter: def __init__(self): self.lock = threading.Lock() self.value = 0 def increment(self): self.lock.acquire() self.value = v

  • Python线程创建和终止实例代码

    python主要是通过thread和threading这两个模块来实现多线程支持. python的thread模块是比較底层的模块,python的threading模块是对thread做了一些封装,能够更加方便的被使用.可是python(cpython)因为GIL的存在无法使用threading充分利用CPU资源,假设想充分发挥多核CPU的计算能力须要使用multiprocessing模块(Windows下使用会有诸多问题). 假设在对线程应用有较高的要求时能够考虑使用Stackless Pyt

  • Python多线程爬虫实战_爬取糗事百科段子的实例

    多线程爬虫:即程序中的某些程序段并行执行, 合理地设置多线程,可以让爬虫效率更高 糗事百科段子普通爬虫和多线程爬虫 分析该网址链接得出: https://www.qiushibaike.com/8hr/page/页码/ 多线程爬虫也就和JAVA的多线程差不多,直接上代码 ''' #此处代码为普通爬虫 import urllib.request import urllib.error import re headers = ("User-Agent","Mozilla/5.0

  • python回调函数中使用多线程的方法

    下面的demo是根据需求写的简单测试脚本 #!/usr/bin/env python # coding: utf-8 # 第一个列表为依赖组件和版本号,后面紧跟负责人名称 # 接着出现第二个以来组建列表,负责人为空了 # 所以根据需求需要对组件.版本号.负责人进行不同处理 # 这时在for循环中根据if判断,写回调函数处理 # 格式不一致数据的测试数据 a = [[u'tool-1', u'1.9.13'], u'xiaowang', u'xiaoqu', [u'tool-2', u'1.9.2

  • Python之多线程爬虫抓取网页图片的示例代码

    目标 嗯,我们知道搜索或浏览网站时会有很多精美.漂亮的图片. 我们下载的时候,得鼠标一个个下载,而且还翻页. 那么,有没有一种方法,可以使用非人工方式自动识别并下载图片.美美哒. 那么请使用python语言,构建一个抓取和下载网页图片的爬虫. 当然为了提高效率,我们同时采用多线程并行方式. 思路分析 Python有很多的第三方库,可以帮助我们实现各种各样的功能.问题在于,我们弄清楚我们需要什么: 1)http请求库,根据网站地址可以获取网页源代码.甚至可以下载图片写入磁盘. 2)解析网页源代码,

  • Python实现可设置持续运行时间、线程数及时间间隔的多线程异步post请求功能

    本文实例讲述了Python实现可设置持续运行时间.线程数及时间间隔的多线程异步post请求功能.分享给大家供大家参考,具体如下: #coding=utf8 ''' random.randint(a, b):用于生成一个指定范围内的整数. 其中参数a是下限,参数b是上限,生成的随机数n: a <= n <= b random.choice(sequence):从序列中获取一个随机元素 参数sequence表示一个有序类型(列表,元组,字符串) ''' import httplib,json im

  • Python基于ThreadingTCPServer创建多线程代理的方法示例

    本文实例讲述了Python基于ThreadingTCPServer创建多线程代理的方法.分享给大家供大家参考,具体如下: #coding=utf8 from BaseHTTPServer import BaseHTTPRequestHandler from SocketServer import ThreadingTCPServer import gzip from StringIO import StringIO import logging logging.basicConfig(level

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

    本文研究的主要是Python多线程threading和multiprocessing模块的相关内容,具体介绍如下. 线程是一个进程的实体,是由表示程序运行状态的寄存器(如程序计数器.栈指针)以及堆栈组成,它是比进程更小的单位. 线程是程序中的一个执行流.一个执行流是由CPU运行程序代码并操作程序的数据所形成的.因此,线程被认为是以CPU为主体的行为. 线程不包含进程地址空间中的代码和数据,线程是计算过程在某一时刻的状态.所以,系统在产生一个线程或各个线程之间切换时,负担要比进程小得多. 线程是一

  • python多线程threading.Lock锁用法实例

    本文实例讲述了python多线程threading.Lock锁的用法实例,分享给大家供大家参考.具体分析如下: python的锁可以独立提取出来 复制代码 代码如下: mutex = threading.Lock() #锁的使用 #创建锁 mutex = threading.Lock() #锁定 mutex.acquire([timeout]) #释放 mutex.release() 锁定方法acquire可以有一个超时时间的可选参数timeout.如果设定了timeout,则在超时后通过返回值

  • Python多线程threading创建及使用方法解析

    一.线程创建方法 1. 普通创建 import threading def run(name): for i in range(3): print(name) if __name__ == '__main__': t1 = threading.Thread(target=run, args=("t1",)) t2 = threading.Thread(target=run, args=("t2",)) t1.start() t2.start() ----------

  • python threading和multiprocessing模块基本用法实例分析

    本文实例讲述了python threading和multiprocessing模块基本用法.分享给大家供大家参考,具体如下: 前言 这两天为了做一个小项目,研究了一下python的并发编程,所谓并发无非多线程和多进程,最初找到的是threading模块,因为印象中线程"轻量...","切换快...","可共享进程资源..."等等,但是没想到这里水很深,进而找到了更好的替代品multiprocessing模块.下面会讲一些使用中的经验. 后面出现的

  • Python多线程threading模块用法实例分析

    本文实例讲述了Python多线程threading模块用法.分享给大家供大家参考,具体如下: 多线程 - threading python的thread模块是比较底层的模块,python的threading模块对thread做了一些包装,可以更加方便的被使用. 1. 使用threading模块 单线程执行 #coding=utf-8 import time def saySorry(): print('跑一圈') time.sleep(1) if __name__ == "__main__&qu

  • python如何重载模块实例解析

    本文首先介绍了Python中的模块的概念,谈到了一个模块往往由多个模块组成,然后通过具体实例,分析了模块重载的相关内容,具体介绍如下. 模块是Python程序架构的一个核心概念,较大的程序往往以多个模块文件的形式呈现,一个模块被设计成主文件或顶层文件,用来启动整个Python程序.每个以.py为后缀的Python源代码文件都是一个模块,其他文件可通过"导入"读取这个模块的内容.从一般意义上讲,模块就是变量名的封装.如写一个模块test.py,包含一个两个变量名name.age. nam

  • Python多线程Threading、子线程与守护线程实例详解

    本文实例讲述了Python多线程Threading.子线程与守护线程.分享给大家供大家参考,具体如下: 线程与进程: 线程对于进程来说,就好似工厂里的工人,分配资源是分配到工厂,工人再去处理. 线程是被系统独立调度和分派的基本单位,线程自己不拥有系统资源,只拥有一点儿在运行中必不可少的资源,但它可与同属一个进程的其它线程共享进程所拥有的全部资源. 在单个程序中同时运行多个线程完成不同的工作,称为多线程 对于IO密集型的程序来说,多线程可以利用读IO的时间去做其他事[IO并不占用CPU,这就好像A

  • python的time模块和datetime模块实例解析

    这篇文章主要介绍了python的time模块和datetime模块实例解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 1. 将当前时间转成字符串 strftime 方法,并输出 import datetime # 获取当前时间 datetime.datetime.now() print(datetime.datetime.now()) # 输出时间格式数据:2019-11-28 20:39:25.485711 now_time=str(da

  • 对Python多线程读写文件加锁的实例详解

    Python的多线程在io方面比单线程还是有优势,但是在多线程开发时,少不了对文件的读写操作.在管理多个线程对同一文件的读写操作时,就少不了文件锁了. 使用fcntl 在linux下,python的标准库有现成的文件锁,来自于fcntl模块.这个模块提供了unix系统fcntl()和ioctl()的接口. 对于文件锁的操作,主要需要使用 fcntl.flock(fd, operation)这个函数. 其中,参数 fd 表示文件描述符:参数 operation 指定要进行的锁操作,该参数的取值有如

  • Python 多线程Threading初学教程

    1.1 什么是多线程 Threading 多线程可简单理解为同时执行多个任务. 多进程和多线程都可以执行多个任务,线程是进程的一部分.线程的特点是线程之间可以共享内存和变量,资源消耗少(不过在Unix环境中,多进程和多线程资源调度消耗差距不明显,Unix调度较快),缺点是线程之间的同步和加锁比较麻烦. 1.2 添加线程 Thread 导入模块 import threading 获取已激活的线程数 threading.active_count() 查看所有线程信息 threading.enumer

随机推荐