进程
进程,描述的是程序的执行过程,是运行着程序的代表,在操作系统中,每个进程的内存空间都是独立的,使用多进程并发有两个缺点:一是内核的管理成本高,而是无法简单地通过内存同步数据(进程运行的虚拟内存空间),很不方便,于是多线程模式就出现了。
线程
线程是操作系统能够运行运算调度的最小单位。它被包含在进程之中,是进程中实际运作的单位,一条线程指的是进程中单一顺序的控制流,一个进程中可以并发多个线程,每条线程并行执行不同的任务。线程总是在进程之内的。一个进程至少会包含一个线程。虽然一个进程中可以并行运行多个线程,而且各个线程之间可以访问进程地址空间的每一个内存地址。
虽然共享地址空间可以方便地共享对象,但这也导致一个问题,任何一个进程出错时,进程中的所有线程都会跟着一起崩溃。
线程内存占用
单个线程消耗内存过多,64位的linux为每个线程的栈分配了8MB的内存,通过ulimit -s可以查看线程的默认分配的内存。单位kb
线程上下文切换
线程的切换是由内核控制的,什么时候会切换线程呢?当时间片用尽,当调用阻塞方法时,CPU都会切换到其他下次讷航那个执行,一次上下围切换的成本在及时纳秒到几个微秒间,当线程数量众多时,这些切换会消耗绝大部分的CPU运算能力。
实现高并发的一个思路就是将内核实现的请求切换工作,交给用户态的代码完成。
协程
什么是协程
协程是用户态的线程,通常创建协程时,会从进程的堆中分配一段内存作为协程的栈。线程的栈有8MB,而协程的栈大小通常只有几十KB。而且C库的内存池不会给协程预分配内存,因为它感知逼到协程的存在。这样更低的内存空间为高并发提供了保证
协程的调度
每个协程有独立的栈,而栈即保留了变量的值,也保留了函数的调用关系,参数和返回值,CPU中栈寄存器SP指向了当前协程的栈,而指令寄存器IP保留着下一条要执行的指令地址。因此从协程1切换到协程2的时候,首先要把SP、IP寄存器的值为线程1保存下来,再从内存中找出协程2上一次切换前保存好的寄存器值,写入CPU的寄存器,这样就完成了协程切换(Swoole4实现)
总结
为什么要搞出协程:
1.节省CPU资源,避免系统内核级的线程频繁切换,造成CPU资源浪费,而协程是用户态的线程,用于可以自行控制协程的创建和销毁,可以避免系统级线程上下文切换造成的资源浪费。
2.节约内存,在64位的Linux中,一个线程需要分配8MB占内存和64M堆内存,系统内存制约导致无法开启更多的线程实现高并发。而在协程编程模式下,可以轻松有十几万协程。
3.稳定性,线程之间通过内存来共享数据,也导致任何一个线程出错时,进程中所有下次讷航那个会跟着一起崩溃(真的会这样吗?)
4.开发效率,使用协程在开发程序之中,可以很方便的将一些耗时的IO操作异步化,例如写文件、耗时IO请求等。
参考文章:
https://zhuanlan.zhihu.com/p/337072647
标签:协程,线程,内存,进程,CPU,切换 From: https://www.cnblogs.com/Wangzx000/p/17340087.html