Python 高级学习#1 多线程编程

本文介绍了Python的多线程机制,包括进程与线程的概念,重点讲解了Python中的全局解释器锁(GIL)以及如何使用threading模块进行多线程编程。还探讨了生产者-消费者问题和Queue模块在多线程中的应用。
摘要由CSDN通过智能技术生成

本章将了解python的多线程机制和GIL,了解threading模块与thread模块的区别和关系,熟练掌握使用threading.Thread进行多线程执行。

什么是多线程?

引言

在多线程(Multithread)编程出现之前,电脑程序的运行由一个执行序列组成,执行序列按顺序在主机的CPU运行。即使子任务相互独立,互相无关时也是按照一条线的顺序执行。
所以多线程编程的目的就是并行的运行这些相互独立的子任务,大幅度的提高整个任务的效率。
多线程编程对于某些任务是非常理想的,这些任务通常具有以下特点:

  • 本质是异步的,需要有多个并发事物。
  • 各个事物的运行顺序可以是不确定的,随机的,不可预测的。
  • 这些子任务可能需要计算出一个中间结果,最终合并为最后的结果。
  • 通常,运算密集型的任务比较容易分隔成多个子任务,如果使用单线程处理,则要处理多个外部输入源就很难。

一个顺序执行的程序要从每个IO终端信道检查用户输入时,程序无论如何也不能在读取IO终端信道的时候阻塞。因为用户输入的到达是不确定的,阻塞会导致其他IO信息的数据不能被处理。所以顺序执行通常使用非阻塞IO,或带有计时器的阻塞IO。

进程与线程

计算机程序只不过是磁盘中可执行的二进制的数据,他们只有在被读取到内存中,被操作系统调用的时候才开始他们的生命周期。
进程使程序的一次执行。**每个进程都有自己独立的地址空间、内存、数据栈以及其他记录其运行轨迹的辅助数据。**操作系统管理在其上运行的所有进程,并为这些进程公平的分配时间。进程也可以通过fork和spawn来完成其他任务。不过各个进程之间相互独立,所以只能使用进程间通讯(IPC)的方式,而不能直接共享信息。

线程跟进程有些相似,不同的是,所有线程运行在同一个进程中,共享相同的运行环境。他们可以想象成是在进程中并行运行的迷你进程。线程有开始、顺序执行、结束三部分。它有一个自己的指令指针,记录自己运行到什么地方,线程的运行可能被抢占(中断),或者暂时的被挂起(也叫睡眠),让其他的线程运行,这叫做让步。

一个进程中的各个线程之间共享一片数据空间,所以线程之间可以更加方便的共享数据以及相互通信。
然而实际中,对于单核CPU,真正的并发是不可能的,每个线程会被安排成每次只运行一小会,然后就把CPU让出来(系统中断),让其他的线程运行。关于进程与线程更多的内容需要去了解《操作系统原理》。

Python中的多线程

全局解释器锁(GIL)

Python代码的执行由python虚拟机(解释器主循环)来控制。对于python虚拟机的访问由全局解释器锁(GIL)来控制,这个锁保证同一时刻只有一个线程在运行。
在调用外部代码(如C/C++扩展函数)的时候,GIL将会被锁定,直到这个函数结束为止。对此感兴趣的可以查看Python/ceval.c文件。

当一个线程结束计算时,就算是退出。。线程可以调用thread.exit()或者使用python退出进程的标准方法,如sys.exit()结束线程。不过,你不可以直接kill一个线程。

在python中使用线程

通常有两种方式:

  • thread模块:通常不推荐使用,最大原因是当主线程退出时,其他线程没有被清楚就退出了。
  • threading模块:推荐使用,对线程支持更为完善。

这里先从thread模块开始学习。thread模块中,除了产生线程之外,thread模块也提供了基本的同步数据结构的锁对象。start_new_thread()函数是thread模块中的关键函数,其参数为:函数、函数的参数以及可选的关键字参数。这个函数会产生一个新线程来运行。
thread模块函数还有:

  • allocate_lock():分配一个LockType类型的所对象。
  • exit():让线程退出。

LockType类型对象方法:

  • acquire(wait=None):尝试获取所对象。
  • locked():如果获取了锁对象返回True,否则返回False。
  • release():释放锁。
# thread.start_new_thread()使用例子
import thread
from time import ctime,sleep

def loop0():
    print 'start loop 0 at: ',ctime()
    sleep(4)
    print 'loop 0 down at ',ctime()

def loop1():
    print 'start loop 1 at: ',ctime()
    sleep(2)
    print 'loop 1 down at ',ctime()

def main():
    print 'start at: ',ctime()
    thread.start_new_thread(loop0,(
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值