进程线程协程
进程
进程是一个实体。每一个进程都有它自己的地址空间,
文本区域(text region)
数据区域(data region)
堆栈(stack region)。
文本区域存储处理器执行的代码;数据区域存储变量和进程执行期间使用的动态分配的内存;堆栈区域存储着活动过程调用的指令和本地变量。
进程是一个“执行中的程序”。程序是一个没有生命的实体,只有处理器赋予程序生命时(操作系统执行之),它才能成为一个活动的实体,我们称其为进程。
线程
线程,是程序执行流的最小单元。一个标准的线程
线程 ID,
当前指令指针 (PC)
寄存器集合
堆栈
线程是进程中的一个实体,是被系统独立调度和分派的基本单位,线程自己不拥有系统资源,只拥有一点儿在运行中必不可少的资源,但它可与同属一个 进程的其它线程共享进程所拥有的全部资源。一个线程可以创建和撤消另一个线程,同一进程中的多个线程之间可以并发执行。由于线程之间的相互制约,致使线程 在运行中呈现出间断性。
线程的状态机
线程也有就绪、阻塞和运行三种基本状态。就绪状态是指线程具备运行的所有条件,逻辑上可以运行,在等待处理机;运行状态是指线程占有处理机正在运行;阻塞状态是指线程在等待一个事件(如某个信号量),逻辑上不可执行。每一个程序都至少有一个线程,若程序只有一个线程,那就是程序本身。线程是程序中一个单一的顺序控制流程。进程内一个相对独立的、可调度的执行单元,是系统独立调度和分派 CPU 的基本单位指运行中的程序的调度单位。在单个程序中同时运行多个线程完成不同的工作,称为多线程。
线程是程序中一个单一的顺序控制流程。进程内一个相对独立的、可调度的执行单元,是系统独立调度和分派 CPU 的基本单位指运行中的程序的调度单位。在单个程序中同时运行多个线程完成不同的工作,称为多线程。
协程
协程 coroutine 和线程一样共享堆,不共享栈,协程由程序员在协程的代码里显示调度,实现用户态中的切换。因此被认为更轻量,开销更低。协程同一时间只能有一个协程运行,golang 的 goroutine 采用的线程的方式,可能存在并行。
选型
进程、线程、协程的关系和区别:
进程拥有自己独立的堆和栈,既不共享堆,亦不共享栈,进程由操作系统调度。
线程拥有自己独立的栈和共享的堆,共享堆,不共享栈,线程亦由操作系统调度 (标准线程是的)。
协程和线程一样共享堆,不共享栈,协程由程序员在协程的代码里显示调度。
CPU 密集型应用多核的环境下,多线程可以充分利用 CPU
IO 密集型应用理论上协程或者 NIO 的处理方式较佳
线程使用
创建线程
JAVA 有 2 种方式实现
继承 java.lang.Thread 类
实现 java.lang.Runnable 接口,并重写 run 方法
启动 / 暂停线程
thread.start()
thread.stop()
互斥
使用 synchronized 关键字声明的方法,会在线程间进行同步。可以视为不同线程竞争一把锁。当线程运行时加锁,结束运行或异常退出时释放
中断
调用 thread.interrupt() 方法让线程进入中断 interrupted 状态,可通过调用 isInterrupted 来确认是否进入中断状态
等待 / 唤醒
调用 thread.wait() 方法让线程进入等待状态,进入此状态的线程可被其他线程的 notify()/notifyAll() 方法唤醒继续执行下文,也可被 interrupt() 进入中断如果执行 wait 时指定了时间。那么当计时器到达指定时间后,如果没有被 notify 唤醒,该线程也会被唤醒。
状态机图例