Python Web学习笔记之Python多线程和多进程、协程入门
进程和线程究竟是什么?如何使用进程和线程?什么场景下需要使用进程和线程?协程又是什么?协程和线程的关系和区别有哪些?
程序切换-CPU时间的分配
首先,我们的任何一个程序都需要运行在一个操作系统中,如 Windows XP, RedHat Linux, FreeBSD, AIX 等;
其次,在操作系统中运行的程序,不止一个,而是成百上千个不同功能的程序,如键盘驱动,显示器驱动,HTTP服务,游戏,聊天,网页......;
最后,CPU等资源是有限的,在这成百上千个程序中,不可能每个程序都占用一个 CPU 来运行,也不可能每个程序只运行一次很短的时间;
那么如何来给应用程序分配 CPU,内存等确定数量的资源?
通过 程序切换 来实现
是指,操作系统自动为每个程序分配一些 CPU/内存/磁盘/键盘/显示器 等资源的使用时间,过期后自动切换到下一个程序。
当然,被切换的程序,如果没有执行完,它的状态会被保存起来,方便下次轮询到的时候继续执行。
实际中,这种切换很快(毫秒级),所以我们感觉不到,好像电脑能自然的同时执行多个软件。
进程
进程,就是这种“程序切换”的第一种方式。
定义
进程,是执行中的计算机程序。也就是说,每个代码在执行的时候,首先本身即是一个进程。
一个进程具有:就绪,运行,中断,僵死,结束等状态(不同操作系统不一样)。
使用
-
用户编写代码(代码本身是以进程运行的)
-
启动程序,进入进程“就绪”状态
-
操作系统调度资源,做“程序切换”,使得进程进入“运行”状态
-
结束/中断
程序执行完,则进入“结束”状态
程序未执行完,但操作系统达到“程序切换”的要求,进入“中断”状态,等待下次被调度后执行
特性
-
每个程序,本身首先是一个进程
-
运行中每个进程都拥有自己的地址空间、内存、数据栈及其它资源。
-
操作系统本身自动管理着所有的进程(不需要用户代码干涉),并为这些进程合理分配可以执行时间。
-
进程可以通过派生新的进程来执行其它任务,不过每个进程还是都拥有自己的内存和数据栈等。
-
进程间可以通讯(发消息和数据),采用 进程间通信(IPC) 方式。
说明
-
多个进程可以在不同的 CPU 上运行,互不干扰
-
同一个CPU上,可以运行多个进程,由操作系统来自动分配时间片
-
由于进程间资源不能共享,需要进程间通信,来发送数据,接受消息等
多进程,也称为“并行”。
更多信息
线程
线程,也是“程序切换”的一种方式。
定义
线程,是在进程中执行的代码。
一个进程下可以运行多个线程,这些线程之间共享主进程内申请的操作系统资源。
在一个进程中启动多个线程的时候,每个线程按照顺序执行。现在的操作系统中,也支持线程抢占,也就是说其它等待运行的线程,可以通过优先级,信号等方式,将运行的线程挂起,自己先运行。
使用
-
用户编写包含线程的程序(每个程序本身都是一个进程)
-
操作系统“程序切换”进入当前进程
-
当前进程包含了线程,则启动线程
-
多个线程,则按照顺序执行,除非抢占
特性
-
线程,必须在一个存在的进程中启动运行
-
线程使用进程获得的系统资源,不会像进程那样需要申请CPU等资源
-
线程无法给予公平执行时间,它可以被其他线程抢占,而进程按照操作系统的设定分配执行时间
-
每个进程中,都可以启动很多个线程
说明
多线程,也被称为”并发“执行。
更多阅读:
进程和线程的区别
一个进程中的各个线程与主进程共享相同的资源,与进程间互相独立相比,线程之间信息共享和通信更加容易(都在进程中,并且共享内存等)。
线程一般以并发执行,正是由于这种并发和数据共享机制,使多任务间的协作成为可能。
进程一般以并行执行,这种并行能使得程序能同时在多个CPU上运行;
区别于多个线程只能在进程申请到的的“时间片”内运行(一个CPU内的进程,启动了多个线程,线程调度共享这个进程的可执行时间片),进程可以真正实现程序的“同时”运行(多个CPU同时运行)。
进程和线程的常用应用场景
一般来说,在Python中编写并发程序的经验:
-
计算密集型任务使用多进程
-
IO密集型(如:网络通讯)任务使用多线程,较少使用多进程.
这是由于 IO操作需要独占资源,比如:
-
网络通讯(微观上每次只有一个人说话,宏观上看起来像同时聊天)每次只能有一个人说话
-
文件读写同时只能有一个程序操作(如果两个程序同时给同一个文件写入 'a', 'b',那么到底写入文件的哪个呢?)
都需要控制资源每次只能有一个程序在使用,在多线程中,由主进程申请IO资源,多线程逐个执行,哪怕抢占了,也是逐个运行,感觉上“多线程”并发执行了。
如果多进程,除非一个进程结束,否则另外一个完全不能用,显然多进程就“浪费”资源了。
当然如上解释可能还不足够立即理解问题所在,让我们通过不断的实操来体验其中的“门道”。
协程
协程,也是”程序切换“的一种。
这里提一个特殊的“线程”,也就是协程的概念。
定义
简单说,协程也是线程,只是协程的调度并不是由操作系统调度,而是自己”协同调度“。也就是”协程是不通过操作系统调度的线程“。当然,实际要比这更复杂一些,本课程不研究协程技术,对于这个很有挑战的技术,在我们完全掌握了进程线程后,自然会理解问题渊源。
协程,又称微线程。
说明
协程的主要特色是:
协程间是协同调度的,这使得并发量数万以上的时候,协程的性能是远远高于线程。
注意这里也是“并发”,不是“并行”。