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定时杀进程
Jun 06 Python
解决python2.7 查询mysql时出现中文乱码
Oct 09 Python
Python实现公历(阳历)转农历(阴历)的方法示例
Aug 22 Python
Python中的并发处理之asyncio包使用的详解
Apr 03 Python
Python使用ConfigParser模块操作配置文件的方法
Jun 29 Python
使用Python获取网段IP个数以及地址清单的方法
Nov 01 Python
对python:print打印时加u的含义详解
Dec 15 Python
详解python-图像处理(映射变换)
Mar 22 Python
python实现代码统计程序
Sep 19 Python
Python Lambda函数使用总结详解
Dec 11 Python
python正则表达式匹配IP代码实例
Dec 28 Python
Django利用elasticsearch(搜索引擎)实现搜索功能
Nov 26 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+DBM的同学录程序(5)
2006/10/09 PHP
Gregarius中文日期格式问题解决办法
2008/04/22 PHP
ajax实现无刷新分页(php)
2010/07/18 PHP
PHP创建桌面快捷方式的实例代码
2014/02/17 PHP
jQuery中的RadioButton,input,CheckBox取值赋值实现代码
2014/02/18 PHP
ubuntu下配置nginx+php+mysql详解
2015/09/10 PHP
PHP自定义函数实现assign()数组分配到模板及extract()变量分配到模板功能示例
2018/05/23 PHP
php如何把表单内容提交到数据库
2019/07/08 PHP
js 父窗口控制子窗口的行为-打开,关闭,重定位,回复
2010/04/20 Javascript
精通Javascript系列之数据类型 字符串
2011/06/08 Javascript
JavaScript中常见的字符串操作函数及用法汇总
2015/05/04 Javascript
很不错的两款Bootstrap Icon图标选择组件
2016/01/28 Javascript
ES6中非常实用的新特性介绍
2016/03/10 Javascript
Bootstrap实现带暂停功能的轮播组件(推荐)
2016/11/25 Javascript
利用BootStrap的Carousel.js实现轮播图动画效果
2016/12/21 Javascript
BootStrap Table 后台数据绑定、特殊列处理、排序功能
2017/05/27 Javascript
vue在手机中通过本机IP地址访问webApp的方法
2018/08/15 Javascript
JS实现数据动态渲染的竖向步骤条
2020/06/24 Javascript
[49:30]DOTA2-DPC中国联赛正赛 Dragon vs Dynasty BO3 第二场 3月4日
2021/03/11 DOTA
使用Python导出Excel图表以及导出为图片的方法
2015/11/07 Python
Python探索之爬取电商售卖信息代码示例
2017/10/27 Python
Python3利用Dlib实现摄像头实时人脸检测和平铺显示示例
2019/02/21 Python
Python3+Pycharm+PyQt5环境搭建步骤图文详解
2019/05/29 Python
Django中celery执行任务结果的保存方法
2019/07/12 Python
windows下Pycharm安装opencv的多种方法
2020/03/05 Python
浅谈Python 命令行参数argparse写入图片路径操作
2020/07/12 Python
plt.figure()参数使用详解及运行演示
2021/01/08 Python
阻止移动设备(手机、pad)浏览器双击放大网页的方法
2014/06/03 HTML / CSS
HTML5中使用json对象的实例代码
2018/09/10 HTML / CSS
欧洲最大的化妆品连锁公司:Douglas道格拉斯
2017/05/06 全球购物
6PM官网:折扣鞋、服装及配饰
2018/08/03 全球购物
工商治理实习生的自我评价
2014/01/15 职场文书
九年级英语教学反思
2014/01/31 职场文书
投资合作意向书范本
2015/05/08 职场文书
征求意见函
2015/06/05 职场文书
《雷雨》教学反思
2016/02/20 职场文书