基于Python的多线程模块Threading小结
步入正题前,先准备下基本知识,线程与进程的概念。
相信作为一个测试人员,如果从理论概念上来说其两者的概念或者区别,估计只会一脸蒙蔽,这里就举个例子来说明下其中的相关概念。
平安夜刚过,你是吃到了苹果还是香蕉呢。。。其实当你用手去接下对方苹果的时候,你的手臂就可以比喻成进程,你的五个手指就可以比喻成线程,所以很明显,线程可以说是进程的细化,没有进程就不会有线程。
这里还是说下必要的概念:
进程
是操作系统中当前程序的一次执行。要知道拥有单个CPU的电脑,在严格意义上,一个时间点上操作系统只能进行同一个工作命令。由于计算机的运行速度快,在工作时可以运行一会A代码,运行一会B代码,交错运行,由于运算速度快,所以一般看来它好像可以同时进行多个程序--这就是多进程。
线程
线程是程序中一个单一的顺序控制流程。进程内一个相对独立的、可调度的执行单元,是系统独立调度和分派CPU的基本单位,这里的单位指运行中的程序的调度单位。在单个程序中同时运行多个线程完成不同的工作,称为多线程。线程还可以自己创建、撤销和切换。就像拿苹果,如果一根手指可以办到,那它就是单线程,如果需要多根手指,那就是多线程。
进程和线程的区别
(1)进程是资源的分配和调度的一个独立单元,而线程是CPU调度的基本单元
(2)同一个进程中可以包括多个线程,并且线程共享整个进程的资源(寄存器、堆栈、上下文),一个进程至少包括一个线程。
(3)进程结束后它拥有的所有线程都将销毁,而线程的结束不会影响同个进程中的其他线程的结束
(4)线程是轻量级的进程,它的创建和销毁所需要的时间比进程小很多,所有操作系统中的执行功能都是创建线程去完成的
(5)线程中执行时一般都要进行同步和互斥,因为他们共享同一进程的所有资源(资源竞争)
(6)线程有自己的私有属性TCB,线程id,寄存器、硬件上下文,而进程也有自己的私有属性进程控制块PCB,这些私有属性是不被共享的,用来标示一个进程或一个线程的标志
子进程与子线程的区别
进程和线程的区别在于粒度不同, 进程之间的变量(或者说是内存)是不能直接互相访问的, 而线程可以, 线程一定会依附在某一个进程上执行.我举个例子, 你在Windows下开一个IE浏览器, 这个IE浏览器是一个进程. 你用浏览器去打开一个pdf, IE就去调用Acrobat去打开, 这时Acrobat是一个独立的进程, 就是IE的子进程.而IE自己本身同时用同一个进程开了2个网页, 并且同时在跑两个网页上的脚本, 这两个网页的执行就是IE自己通过两个线程实现的.值得注意的是, 线程仍然是IE的内容, 而子进程Acrobat严格来说就不属于IE了, 是另外一个程序,之所以是IE的子进程, 只是受IE调用而启动的而已。
这里大家可能会疑惑,进程分配内存空间的依据是啥?其实进程建立,系统会为其分配虚拟地址空间4GB(在32位系统中),具体分配情况要取决于该包含的所有可执行模块或dll模块的代码和数据,还包含动态内存分配的空间(如线程中堆栈的分配)
好了,上面介绍了基本的线程及进程的概念,接下来可以开始正题了,这里主要总结下python内的Threading模块
python多线程之Threading
单线程
额,这个忽略吧。。。操作系统单任务的处理,排好队,一个一个来就是单线程。
多线程
多线程Threading一般可以通过两种渠道来实现:一种是通过继承Thread类,重写它的run方法;另一种是创建一个threading.Thread对象,在它的初始化函数(__init__)中将可调用对象作为参数传入,本质上来讲,两种方式一样。
来一发实例:
# -*- coding: utf-8 -*-
import threading
import time #方式二是方式一的具体,方式一为类构造,方式二为方法实例构造,其实本质都是一样,都是调用threading.Thread模块
#方式一
count = 0
class Counter(threading.Thread): def __init__(self, lock, threadName): #注意:一定要显式的调用父类的初始化函数,这里可以指定生成的线程名,可以是*args、**kwargs
#def __init__(self, group=None, target=None, name=None, args=(), kwargs={}),其中group是预留的,将来用于扩展
super(Counter, self).__init__(name=threadName)
self.lock = lock def run(self): global count
self.lock.acquire()
for i in range(100):
count = count + 1
self.lock.release() #方式二
lockA = threading.Lock()
lockB = threading.Lock()
rLock = threading.RLock()
condt = threading.Condition()
event = threading.Event() def add(lockA): global count
#定义当前资源只能单线程访问,锁住后完成资源调用一定要释放锁,不然会造成死锁状态,甚至程序崩溃
lockA.acquire()
for i in range(1000):
count = count + 1
#资源调用完毕,释放锁
lockA.release() def addRunner(): for i in range(2):
th = threading.Thread(target=rloc, args=(rLock,))
#开启线程,从此刻起,多线程开始,主线程继续前行
th.start()
#调用Thread.join[timeout]将会使主调线程堵塞,直到被调用线程运行结束或超时。参数timeout是一个数值类型,表示超时时间
th.join()
print '----- %s is start -----' % th.getName()
print "over" #RLock允许在同一线程中被多次acquire,避免单线程出现思索情况
def rloc(rLock): rLock.acquire()
for i in range(2):
rLock.acquire()
print i,
rLock.release()
rLock.release()
print "over!" def rlocRun(): for i in range(2):
th = threading.Thread(target=rloc, args=(rLock,))
th.start()
print '----- %s is start -----' % th.getName()
print "over" #现在出现复杂的场景,多个线程需要调用多个共同的资源,此时就需要threading.Condition出马,加入简单的说就是A搞完了A的事
# ,就发广播说明自己搞定了,其它人可以进来了,B同理。
def cond(cond):
#适合那种主动休眠,被动唤醒的场景
cond.acquire()
global count
for i in range(1000):
count = count + 1
#唤醒一个挂起的线程(如果存在挂起的线程),提醒当前的挂起的线程看看其它的锁开了没有,如果开了就搞其他的事。
#注意:notify()方法不会释放所占用的琐。
cond.notify()
#wait方法释放内部所占用的琐,同时线程被挂起,直至接收到通知被唤醒或超时
cond.wait(5)
#相信大家应该看出问题来了,最后一个线程咋办列,没人唤醒啊,这个时候应该做过一个判断
cond.release()
print "over!" def condRun():
global condt
for i in range(0, 3):
th = threading.Thread(target=cond, args=(condt, ))
th.start()
print '----- %s is start -----' % th.getName()
print "over" #此时可能会有一点问题,就是线程的同步(并发)问题怎么解决呢?此时threading.Event出马
def even(n, event):
while not event.isSet():
print 'Thread %s is ready' % n
time.sleep(1)
#同condition一样,挂起该线程,等待set开关
event.wait()
while event.isSet():
print 'Thread %s is running' % n
time.sleep(1) def evenRun(): for i in range(0, 2):
th = threading.Thread(target=even, args=(i, event))
th.start()
time.sleep(3)
print '----- event is set -----'
event.set()
time.sleep(3)
print '----- event is clear -----'
event.clear() if __name__ == "__main__": Counter(lockA, "thread1").start()
addRunner()
rlocRun()
condRun()
evenRun()
基于Python的多线程模块Threading小结的更多相关文章
- Python的多线程(threading)与多进程(multiprocessing )
进程:程序的一次执行(程序载入内存,系统分配资源运行).每个进程有自己的内存空间,数据栈等,进程之间可以进行通讯,但是不能共享信息. 线程:所有的线程运行在同一个进程中,共享相同的运行环境.每个独立的 ...
- 基于Python的datetime模块和time模块源码阅读分析
目录 1 前言 2 datetime.pyi源码分步解析 2.1 头部定义源码分析 2.2 tzinfo类源码分析 2.3 date类源码分析 2.4 time类源码分析 2.5 timedelta ...
- Python并发复习2 - 多线程模块threading
一.多线程的调用 threading 模块建立在thread 模块之上.thread模块以低级.原始的方式来处理和控制线程,而threading 模块通过对thread进行二次封装, 提供了更方便的a ...
- Python之多线程:Threading模块
1.Threading模块提供的类 Thread,Lock,Rlock,Condition,Semaphore,Event,Timer,local 2.threading模块提供的常用的方法 (1)t ...
- 【Python】 多线程并发threading & 任务队列Queue
threading python程序默认是单线程的,也就是说在前一句语句执行完之前后面的语句不能继续执行(不知道我理解得对不对) 先感受一下线程,一般情况下: def testa(): sleep(1 ...
- 基于python的多线程暴破脚本
搭建了一个本地wordpress,写一个基于多线程异步I/O的暴力破解 1 测试 提交错误的表单数据时,查看请求参数 登录时发送的cookie 2 登录分析 经过多次测试,发现无论是输入正确的密码还是 ...
- 基于Python的多线程与多进程
1.I/O密集型与计算密集型 多进程适用于I/O密集型 多进程适用于计算密集型 2.没有sleep(T)的多个死循环只能用多进程 3.模块介绍: 1)threading模块(_thread模块已淘汰) ...
- 基于python的extract_msg模块提取outlook邮箱保存的msg文件中的附件
笔者保存了一些outlook邮箱中保存的一些msg格式的邮件文件,现需要将其中的附件提取出来, 当然直接在outlook中就可以另存附件,但outlook默认是不支持批量提取邮件中的附件的 思考过几种 ...
- 基于python第三方requests 模块的HTTP请求类
使用requests模块构造的下载器,首先安装第三方库requests pip install requests 1 class StrongDownload(object): def __init_ ...
随机推荐
- Scrapy爬虫(4)爬取豆瓣电影Top250图片
在用Python的urllib和BeautifulSoup写过了很多爬虫之后,本人决定尝试著名的Python爬虫框架--Scrapy. 本次分享将详细讲述如何利用Scrapy来下载豆瓣电影To ...
- 4.4 explain 之 possible_keys 、key、key_len
一.possible_keys 显示可能应用在这张表中的索引,一个或多个. 查询涉及到的字段上若存在索引,则该索引将被列出,但不一定被查询实际使用. 二.key 实际使用的索引.如果为null,则没有 ...
- 汇编语言--微机CPU的指令系统(五)(移位操作指令)
(5) 移位操作指令 移位操作指令是一组经常使用的指令,它包括算术移位.逻辑移位.双精度移位.循环移位和带进位的循环移位等五大类. 移位指令都有指定移动二进制位数的操作数,该操作数可以是立即数或CL的 ...
- 工作笔记-table问题汇总(vue单文件组件)
1.vue: computed里定义的数据,在其他地方不能再重新赋值,会报错: Computed property "xxxxxx" was assigned to but it ...
- DOM技术
DOM概述 DOM:Document Object Model(文档对象模型)(DOM核心就是 文档变对象,标签也变对象,属性也变对象,反正就是把标记文档拆散) 用来将标记型对象封装成对象,并将标记型 ...
- git命令详解( 九 )
此为git第九篇记录 整理提交记录 Git Cherry-pick 交互式的 rebase Git Tags Git Describe 整理提交记录 之前我们已经学习了 Git 的基础知识 ...
- 一次断电引发的svn数据库故障
作者:朱金灿 来源:http://blog.csdn.net/clever101 昨天办公室停电了.然后今天更新svn数据库时出现一个不能读取文件:End of file found的错误,具体如下图 ...
- springboot 整合 redis
jedis 和 lettuce 都是用来连接 redis 的客户端,jedis 如果不使用连接池是非线程安全的,lettuce 使用 netty 线程安全且并发性能更好: springboot 2.x ...
- ngx-moment汉化
1.导入汉化文件 import '../../../node_modules/moment/locale/zh-cn.js' 2.使用汉化 <span>{{item.time|amLoca ...
- python3接收、解析邮件
邮件接收 python3可以使用poplib.POP3进行邮件接收,具体如下: import poplib from email.parser import Parser def get_email( ...