从进程、线程、协程到GMP(二):GMP

阅读本节之前,强烈建议先阅读一下第一节从进程、线程、协程到GMP(一):进程、线程、协程 - 知乎 (zhihu.com)GMP 模型基本概念GMP 本质上是一个多对多的用户级线程模型,下图是 GMP 的一个基本架构图在Go语言的早期版本中(Go 1.1之前) 调度模型是GM模型,而不是现在的GMP模型, 其存在以下缺点:GO 程序运行流程goroutine 一般分为三种,分别是:Go所创建的第一个内核级线程称为 m0 也叫主线程,一个 Go 进程只有一个 m0。这个内核级线程对应的实例在全局变量runtime.m0 中,不在 heap 上分配。m0负责执行初始化操作和启动第一个G(主协程), 在之后 m0就和其他的M一样了。 runtime 每创建一个内核级线程M都会创建一个g0 ,即每个 M 都会有一个自己的 g0。在执行调度函数或系统调用时会使用g0的栈空间, g0 其实就是内核级线程的用户栈

线程和协程有什么区别呢?

协同程序(coroutine)与多线程情况下的线程比较类似:有自己的堆栈,自己的局部变量,有自己的指令指针(IP,instruction pointer),但与其它协同程序共享全局变量等很多信息。协程(协同程序): 同一时间只能执行某个协程。开辟多个协程开销不大。协程适合对某任务进行分时处理。线程: 同一时间可以同时执行多个线程。开辟多条线程开销很大。线程适合多任务同时处理。1.协程,即协作式程序,其思想是,一系列互相依赖的协程间依次使用CPU,每次只有一个协程工作,而其他协程处于休眠状态。协程实际上是在一个线程中,只不过每个协程对CUP进行分时,协程可以访问和使用unity的所有方法和component2.线程,多线程是阻塞式的,每个IO都必须开启一个新的线程,但是对于多CPU的系统应该使用thread,尤其是有大量数据运算的时刻,但是IO密集型就不适合;而且thread中不能操作unity的很多方法和component

Lua协程(Coroutine)

协程是一种具备独立执行状态的程序片段,拥有自己的局部变量、栈和指令指针,同时与其它协程共享全局变量和其他资源。相较于线程,协程在任何时刻只能执行一个,且在明确指令下才会暂停执行。协程状态包括四种:运行、等待、挂起和死亡。创建协程使用`coroutine.create`函数,传入待执行的匿名函数,返回新协程。新协程默认处于等待状态,需通过`coroutine.resume`启动运行。协程的关键在于`yield`函数,它能挂起当前协程,等待`resume`函数恢复执行。通过`resume`,协程执行至`yield`处暂停,再继续执行。此特性使得协程实现非阻塞式异步编程。协程运行完毕后进入死亡状态,调用`resume`无法再次执行。当协程发生错误时,调用`resume`和`pcall`一样,运行在保护模式下,错误被隐藏,而非抛出。除了`create`,`wrap`函数同样用于创建协程,返回值为函数,若协程内发生错误,将终止协程并抛出错误

进程线程协程的区别

一、概念  1、进程进程是具有一定独立功能的程序关于某个数据集合上的一次运行活动,进程是系统进行资源分配和调度的一个独立单位。每个进程都有自己的独立内存空间,不同进程通过进程间通信来通信。由于进程比较重量,占据独立的内存,所以上下文进程间的切换开销(栈、寄存器、虚拟内存、文件句柄等)比较大,但相对比较稳定安全。  2、线程线程是进程的一个实体,是CPU调度和分派的基本单位,它是比进程更小的能独立运行的基本单位.线程自己基本上不拥有系统资源,只拥有一点在运行中必不可少的资源(如程序计数器,一组寄存器和栈),但是它可与同属一个进程的其他的线程共享进程所拥有的全部资源。线程间通信主要通过共享内存,上下文切换很快,资源开销较少,但相比进程不够稳定容易丢失数据。  3、协程协程是一种用户态的轻量级线程,协程的调度完全由用户控制。协程拥有自己的寄存器上下文和栈。协程调度切换时,将寄存器上下文和栈保存到其他地方,在切回来的时候,恢复先前保存的寄存器上下文和栈,直接操作栈则基本没有内核切换的开销,可以不加锁的访问全局变量,所以上下文的切换非常快