python多线程编程

python多线程编程

  1. 为啥使用多线程?
  • 有时候计算机要处理的任务之间没有因果关系,都是独立的,也就是说任务的结果不会影响其他任务,我们就会希望计算机并行的处理多个任务,这就要使用多线程。当然还有其他方式来实现多任务并行处理,比如说串行程序使用一个或多个计时器来实现一个多路复用的方案,一个串行程序需要从每个I/O终端通道来检查用户的输入,然而程序在读取I/O时不能阻塞,因为用户的输入是不确定时间的,阻塞会影响其他I/O通道的处理,串行程序必须使用非阻塞I/O或拥有计时器的阻塞I/O。由于串行程序只有一个执行线程,为了防止执行其中某一个任务占用太多时间,并对用户的响应进行合理分配,实现起来会有非常复杂的控制流,难以维护。
  1. 进程和线程到底是啥?
  • 进程(重量级进程)是一个执行中的程序,每个进程都有自己的地址空间、内存、数据栈、以及其他一些用于跟踪执行的辅助数据,操作系统管理其上所有进程的执行,为这些进程分配时间。进程可以通过派生(fork或spawn)新的进程来执行其他任务,由于每个进程都有自己的地址空间和内存。所以进程间只能通过进程间通信的方式共享信息。线程(轻量级进程)与进程类似,但是它们是在一个进程空间下面执行的,并共享上下文,可以将它们认为是在一个主进程中并行运行的一些迷你进程。
  1. python和线程和全局解释器锁
  • python代码是由python虚拟机执行的,python虚拟机其实就是模拟cpu核心,所以,同一时刻只能由一个线程在执行,多线程执行实质上是虚拟机不停的切换执行中的线程,为了保证同一时刻只有一个线程在执行,这里就用到全局解释器锁,所以对虚拟机的访问是由全局解释器锁来控制的。
    1
    2
    3
    4
    5
    6
    7
    8
    1. 设置GIL(Global Interpreter Lock)
    2. 切换一个线程去执行
    3. 执行
    a. 指定数量的字节码指令
    b. 线程主动让出控制权
    4. 切换出线程
    5. 解锁GIL
    6. 重复上述步骤
    当调用外部代码(例如C/C++拓展内置函数),GIL会保持锁定,因为这期间没有python字节码计数,但是可以靠在拓展代码中手动解锁GIL。