Python多线程编程基础

Python多线程编程基础

01 前言

最近又温习了一遍《Python核心编程》的多线程编程部分,整理了一下其中的知识点,只涉及多线程编程的基础知识。如有错误,请评论指出。

多线程是并行执行任务的编程方法。当然,本质上是异步的,每个时刻只能用一个线程运行,但宏观来看是并行的。多线程可以更好地利用计算机资源,提高执行任务的效率,尤其对于I/O密集型应用更是如此。

02 线程和进程

这是两个容易混淆的概念。一般来说,进程>线程。

进程,又称重量级进程,是一个执行中的计算机程序。计算机会为每个进程分配一定的资源。进程可以通过派生新的进程来执行其他任务,进程之间通过进程间通信的方式共享信息。

线程,又称轻量级进程,是在同一个进程下执行的,共享相同的上下文。线程包括开始,执行顺序,结束三部分。进程交替使用某资源,所以可能因为访问顺序不同导致结果不同,这被称为竞态条件

03 线程和Python

这里面涉及到一个叫做全局解释器锁的概念。简单来说

  • Python虚拟机(解释器主循环)控制python代码执行,某一时刻只能执行一个线程

  • 全局解释器锁控制Python虚拟机的访问,即全局解释器锁限制了线程,确保同时只能有一个线程运行

所以,全局解释器锁是python多线程编程的基础机制。

python中关于多线程编程的模块有thread,threading,queue等。其中,thread模块不建议使用,因为它不支持守护线程(即主线程结束时,所有其他线程也都强制结束),并且同步源语很少(下文会提到)。

04 threading模块

threading模块是比thread更高级更好用的模块,Thread类是threading模块的主要执行对象,下面就来简单介绍一下它并讲解几个实例。

Thread对象方法 描述
init() 构造函数,实例化一个线程对象
start() 开始执行该线程
run() 定义线程功能
join() 直至启动的线程终止之前一直挂起

使用Thread类创建线程有很多方法,下面只介绍其中一种:创建Thread的实例,传给它一个函数。

import threading

from time import sleep,ctime

loops = [4,2]

def loop(nloop,nsec):

​ print(‘start loop’,nloop,’at:’,ctime())

​ sleep(nsec)

​ print(‘finish loop’,nloop,’at:’,ctime())

def main():

​ print(‘start threads at:’,ctime())

​ threads = []

​ nloops = range(len(loops))

​ for i in nloops:

​ t = threading.Thread(target=loop,args=(i,loops[i]))

​ threads.append(t)

​ for i in nloops:

​ threads[i].start()

​ for i in nloops:

​ threads[i].join()

​ print(‘all done at:’,ctime())

if name == ‘main‘:

​ main()

结果:

start threads at: Thu May 31 17:28:37 2018
start loop 0 at: Thu May 31 17:28:37 2018
start loop 1 at: Thu May 31 17:28:37 2018
finish loop 1 at: Thu May 31 17:28:39 2018
finish loop 0 at: Thu May 31 17:28:41 2018
all done at: Thu May 31 17:28:41 2018

05 同步原语

多线程编程一个非常重要的方面是同步。因为你肯定不希望一些重要数据因为不同步而出错。

下面就来介绍两种同步原语:

  • 锁/互斥:最简单,最低级的机制

  • 信号量:用于多线程竞争有限资源的情况

锁的作用,顾名思义,就是让获得锁的线程能够完整的执行而不被打断。

锁有两种状态:锁定,未锁定。支持两个函数:获得锁,释放锁。

创建一个锁对象需要引入Lock;获得锁—acquire;释放锁—release。

信号量是一个计数器,资源消耗时递减,资源释放时递增,同样也使用acquire和release。

至于使用嘛,类似这样:

lock = Lock() #创建一个锁对象

lock.acquire() #获得锁

code #需要在锁里执行的代码

lock.release() #释放锁

06 结语

还有queue模块没写,因为几乎没用到,(好吧,其实是懒)等用到的时候在来补充吧。

新手写博客,如有错误,还请各位指正,谢谢!

你可能感兴趣的:(Python)