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中Django框架利用url来控制登录的方法
Jul 25 Python
Python中operator模块的操作符使用示例总结
Jun 28 Python
微信跳一跳python辅助软件思路及图像识别源码解析
Jan 04 Python
python 实现在一张图中绘制一个小的子图方法
Jul 07 Python
python运用sklearn实现KNN分类算法
Oct 16 Python
Pycharm使用远程linux服务器conda/python环境在本地运行的方法(图解))
Dec 09 Python
使用 Python 合并多个格式一致的 Excel 文件(推荐)
Dec 09 Python
python绘制雪景图
Dec 16 Python
Scrapy框架基本命令与settings.py设置
Feb 06 Python
python实现信号时域统计特征提取代码
Feb 26 Python
Python reversed函数及使用方法解析
Mar 17 Python
JAVA SWT事件四种写法实例解析
Jun 05 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 PDO函数库详解
2010/04/27 PHP
PHP面向对象学习笔记之二 生成对象的设计模式
2012/10/06 PHP
PHP错误提示的关闭方法详解
2013/06/23 PHP
PHP实现文件下载详解
2014/11/27 PHP
ThinkPHP实现支付宝接口功能实例
2014/12/02 PHP
php mysql数据库操作类(实例讲解)
2017/08/06 PHP
phpStudy配置多站点多域名方法及遇到的403错误解决方法
2017/10/19 PHP
PHP模型Model类封装数据库操作示例
2019/03/14 PHP
js获取class的所有元素
2013/03/28 Javascript
js 动态加载事件的几种方法总结
2013/12/25 Javascript
详谈javascript中的cookie
2015/06/03 Javascript
数据分析软件之FineReport教程:[5]参数界面JS(全)
2015/08/13 Javascript
JS实现iframe自适应高度的方法示例
2017/01/07 Javascript
浅谈vue引入css,less遇到的坑和解决方法
2018/01/20 Javascript
axios的拦截请求与响应方法
2018/08/11 Javascript
Jquery和CSS实现选择框重置按钮功能
2018/11/08 jQuery
原生JS实现手动轮播图效果实例代码
2018/11/22 Javascript
如何利用nodejs实现命令行游戏
2020/11/24 NodeJs
vue+element UI实现树形表格
2020/12/29 Vue.js
[56:13]DOTA2-DPC中国联赛定级赛 LBZS vs Phoenix BO3第一场 1月10日
2021/03/11 DOTA
基于Python闭包及其作用域详解
2017/08/28 Python
详解js文件通过python访问数据库方法
2019/03/03 Python
对python 调用类属性的方法详解
2019/07/02 Python
python多线程共享变量的使用和效率方法
2019/07/16 Python
Python 窗体(tkinter)下拉列表框(Combobox)实例
2020/03/04 Python
利用简洁的图片预加载组件提升html5移动页面的用户体验
2016/03/11 HTML / CSS
Chemist Warehouse官方海外旗舰店:澳洲第一连锁大药房
2017/08/25 全球购物
比利时家具购买网站:Home24
2019/01/03 全球购物
青年文明号服务承诺
2014/03/31 职场文书
转让协议书范本
2014/09/13 职场文书
募捐感谢信
2015/01/22 职场文书
学校党员干部承诺书
2015/05/04 职场文书
律师催款函范文
2015/06/24 职场文书
2016年寒假生活小结
2015/10/10 职场文书
js实现模拟购物商城案例
2021/05/18 Javascript
Python绘制散点图之可视化神器pyecharts
2022/07/07 Python