要理解线程,首先要理解并发的概念。并发是指在同一时间点,计算机可以同时执行多个任务。当前主流的操作系统,不管是Window系统,还是Linux系统,都是以多任务执行程序的。例如,我们可以在编写Python代码的同时听音乐、发送电子邮件等。
在多任务系统中,每个独立执行的任务(应用程序)称为进程,多个任务可以并发执行。下图是Windows 10系统任务管理器中的进程,从中可以看到当前操作系统中有多个任务同时在执行。
图 1 Windows任务管理器中的进程
严格来说,多任务系统并不是真正地并发执行多个任务,在单核CPU系统中,操作系统会根据很小的时间间隔交替执行多个任务(应用程序),使得这些应用程序看起来就像是在并行运行一样。多核CPU可以做到真正意义上的并发执行。
1、什么是多线程
前面我们编写的Python程序都是从代码开始顺序执行每行代码,代码执行完成之后,结束整个应用程序。这样顺序执行的程序称为单线程程序,单线程程序在同一个时间内只执行一个任务。在实际处理问题的过程中,单线程程序往往不能适应复杂的业务需求。例如,在WEB项目中,多个用户通过浏览器客户端向服务器端发出请求,如果服务器端采用单线程程序处理用户发送的请求,将会导致用户等待响应时间过长,服务效率低下的问题。要想缩短用户等待时间,提高服务效率,可以采用多线程的程序来同时处理多个请求任务。
多线程程序将单个任务按照功能分解成多个子任务来执行,每个子任务称为一个线程,多个线程共同完成主任务的运行过程。例如,前面提到的WEB项目,服务器端主程序将用户的每个请求创建一个线程(子任务)去处理用户的请求,这样就可以提高服务器端的服务性能,缩短用户等待响应时间。
2、进程和线程的区别
进程是每个独立程序在计算机上的一次执行活动。例如,运行中播放器、浏览器等。运行一个程序,操作系统就启动了一个进程,进程加载程序代码、分配程序所需的资源环境,每个进程都有独立的代码和数据空间(进程上下文),进程可以由多条路径并发执行,并发执行的多条路径称为多线程。线程是比进程更小的执行单位,多个线程共享进程的代码、数据空间,但每个线程都有独立的运行栈和程序计数器。
进程是每个独立程序在计算机上的一次执行活动,线程是进程中的一个执行路径,线程依赖于进程而存在。
3、认识线程
先来看一段单线程代码:
import threading
def method1(message):
print(message)
def method2(message):
print(message)
method1(message)
def main():
t1 = threading.Thread(target=method2, args=("hello",))
t1.start()
if __name__ == '__main__':
main()当Python解释器执行这个程序时,首先会执行main()方法,main()方法会启动一个线程,这个启动的线程就是method2()方法,method2()方法逐条执行方法内的语句,并调用method1()方法。程序执行过程如下图所示:

图 2 Python程序的执行过程
Python程序一般由多个模块组成,虽然这些模块都可以独立运行,但一般说来会有一个主模块。在程序执行过程中,Python解释器会首先加载主模块,然后这个主模块再调用其它模块。Python关键字__name__就是标识模块名字的一个系统变量,如果当前模块是主模块,这个系统变量的值是__mian__,若当前模块名称是__mian__,就执行主函数main方法。
Python允许在一个程序中启动多个线程,它通过threading类来实现,下节将详细介绍多线程的创建和启动。
多线程可以允许程序并发执行多个子任务,提高程序运行效率,增强用户体验度。例如,我们经常使用的下载工具就采用了多线程技术,一个下载任务启动后,下载工具把文件平分成n份,然后开n个线程分别下载,最后再组装文件。