并发网络编程学习笔记(3)-线程

/ 0评 / 0

线程(Thread)

线程概述

  1. 概念:
    【1】线程被称为轻量级的进程,也是多任务编程方式
    【2】也可以利用计算机的多CPU资源
    【3】线程可以理解为进程中再开辟的分支任务
  2. 线程特征
    【1】一个进程可以包含多个线程
    【2】线程也是一个运行行为,消耗计算资源
    【3】一个进程中所有线程共享这个进程的资源
    【4】多个线程之间的运行同样互不影响各自运行
    【5】线程的创建和销毁消耗资源远小于进程

多线程编程

创建线程类

  1. 创建步骤
    【1】继承Thread类
    【2】重写__ init __方法添加自己的属性,使用super()加载父类属性【3】重写run()方法
  2. 使用方法
    【1】实例化对象
    【2】调用start自动执行run方法

线程同步互斥

  1. 线程通信方法:线程间使用全局变量进行通信
  2. 共享资源争夺
    • 共享资源:多线程都可以操作的资源称为共享资源。对共享资源的操作代码段称为临界区。
    • 影响: 对共享资源的无序操作可能会带来数据的混乱,或者操作错误。此时往往需要同步互斥机制协调操作顺序。
  3. 同步互斥机制
    • 同步:同步是一种协作关系,为完成操作,线程间形成一种协调,按照必要的步骤有序执行操作。
    • 互斥:互斥是一种制约关系,当一个进程或者线程占有资源时会进行加锁处理,此时其他进程线程就无法操作该资源,直到解锁后才能操作。
  4. 线程Event
    from threading import Event
    e = Event() 创建线程event对象
    e.wait([timeout]) 阻塞等待e被set
    e.set() 设置e,使wait结束阻塞
    e.clear() 使e回到未被设置状态
    e.is_set() 查看当前e是否被设置
  5. 线程锁 Lock
    from threading import Lock
    lock = Lock() 创建锁对象
    lock.acquire() 上锁 如果lock已经上锁再调用会阻塞
    lock.release() 解锁

死锁

  1. 两个或两个以上的线程在执行过程中,由于竞争资源或者由于彼此通信而造成的一种阻塞的现象,若无外力作用,它们将无法推进下去。此时系统处于死锁状态或系统生产了死锁。
  2. 死锁产生条件
    • 互斥条件:线程使用了互斥方法,使用一个资源时其他线程无法使用
    • 请求和保持条件:指线程已经保持至少一个资源,但又提出了新的资源请求,在获取到新的资源前不会释放自己保持的资源。
    • 不剥夺条件:不会受到线程外部的干扰,如系统强制终止线程等。
    • 环路等待条件:在发生死锁时,必须存在一个线程------资源的环形链,如T0正在等待一个T1占用的资源.....Tn正在等待已被T0占用的资源。
  3. 如何避免死锁
    • 逻辑清晰,不要同进出现上述死锁产生的四个条件
    • 通过测试工程师进行死锁检测

GIL问题

  1. 什么是GIL问题(全局解释器锁)由于python解释器设计中加入了解释器锁,导致python解释器同一时间只能解释执行一个线程,大降低了线程的执行效率。
  2. 后果遇阻塞线程会主动让出解释器,去解释其他线程。python多线程在执行多阻塞任务时可以提升程序效率,其他情况并不能对效率有所提升。
  3. 处理* 尽量使用进程完成无阻塞的并发行为
    * 不使用c作为解释器 (可以用Java C#)
    * Guido的声明:<http://www.artima.com/forums/flat.jsp?forum=106&thread=214235>
  4. 结论
    • GIL问题与Python语言本身没什么关系,属于解释器设计的历史问题。
    • 在无阻塞状态下,多线程程序执行效率并不高,甚至还不如单线程效率。
    • Python多线程只适用于执行有阻塞延迟的任务情形

进程、线程特点对比

发表评论

您的电子邮箱地址不会被公开。 必填项已用*标注