Python多线程模块Threading用法示例小结


Posted in Python onNovember 09, 2019

本文实例讲述了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程序设计有所帮助。

Python 相关文章推荐
在Python中封装GObject模块进行图形化程序编程的教程
Apr 14 Python
python 列表,数组和矩阵sum的用法及区别介绍
Jun 28 Python
Pythony运维入门之Socket网络编程详解
Apr 15 Python
基于Python的PIL库学习详解
May 10 Python
Python3离线安装Requests模块问题
Oct 13 Python
Python3 sys.argv[ ]用法详解
Oct 24 Python
Python的缺点和劣势分析
Nov 19 Python
Python使用urllib模块对URL网址中的中文编码与解码实例详解
Feb 18 Python
对python中各个response的使用说明
Mar 28 Python
Django serializer优化类视图的实现示例
Jul 16 Python
Python制作简单的剪刀石头布游戏
Dec 10 Python
Django集成富文本编辑器summernote的实现步骤
May 31 Python
Python for循环及基础用法详解
Nov 08 #Python
python常用排序算法的实现代码
Nov 08 #Python
python分布式编程实现过程解析
Nov 08 #Python
详解mac python+selenium+Chrome 简单案例
Nov 08 #Python
python manage.py runserver流程解析
Nov 08 #Python
详解python中docx库的安装过程
Nov 08 #Python
numpy.array 操作使用简单总结
Nov 08 #Python
You might like
php 无限级缓存的类的扩展
2009/03/16 PHP
兼容PHP和Java的des加密解密代码分享
2014/06/26 PHP
PHP设计模式之状态模式定义与用法详解
2018/04/02 PHP
基于jquery的让页面控件不可用的实现代码
2010/04/27 Javascript
使用jquery mobile做幻灯播放效果实现步骤
2013/01/04 Javascript
JQUERY dialog的用法详细解析
2013/12/19 Javascript
jquery事件重复绑定的快速解决方法
2014/01/03 Javascript
javascript结合ajax读取txt文件内容
2014/12/05 Javascript
jQuery实现复选框批量选择与反选的方法
2015/06/17 Javascript
跟我学习javascript的垃圾回收机制与内存管理
2015/11/23 Javascript
每日十条JavaScript经验技巧(一)
2016/06/23 Javascript
js倒计时小实例(多次定时)
2016/12/08 Javascript
Axios学习笔记之使用方法教程
2017/07/21 Javascript
对Angular中单向数据流的深入理解
2018/03/31 Javascript
微信小程序实现发红包功能
2018/07/11 Javascript
用Fundebug插件记录网络请求异常的方法
2019/02/21 Javascript
js/jQuery实现全选效果
2019/06/17 jQuery
jQuery zTree树插件的使用教程
2019/08/16 jQuery
JavaScript对象原型链原理解析
2020/01/22 Javascript
jQuery实现颜色打字机的完整代码
2020/03/19 jQuery
openlayers 3实现车辆轨迹回放
2020/09/24 Javascript
vue.js页面加载执行created,mounted的先后顺序说明
2020/11/07 Javascript
[01:03:37]Secret vs VGJ.S Supermajor小组赛C组 BO3 第二场 6.3
2018/06/04 DOTA
python list转矩阵的实例讲解
2018/08/04 Python
用Python做一个久坐提醒小助手的示例代码
2020/02/10 Python
详解Django3中直接添加Websockets方式
2020/02/12 Python
postman和python mock测试过程图解
2020/02/22 Python
谈谈Python:为什么类中的私有属性可以在外部赋值并访问
2020/03/05 Python
python标准库OS模块详解
2020/03/10 Python
解决Python Matplotlib绘图数据点位置错乱问题
2020/05/16 Python
香港钟表珠宝首饰商城:OneMallTime网摩间
2016/10/14 全球购物
三爱活动实施方案
2014/03/19 职场文书
2014年节能减排工作总结
2014/12/06 职场文书
公司欠款证明
2015/06/24 职场文书
基层党建工作简报
2015/07/21 职场文书
用 Python 元类的特性实现 ORM 框架
2021/05/19 Python