操作系统-进程/线程/协程1-4
1.进程、线程、协程、goroutine区别,windows的协程和goroutine区别
进程:既不共享堆,也不共享栈。操作系统调度。进程是系统进行资源分配和调度的一个独立单位,每个进程都有自己的独立内存空间,拥有自己独立的堆和栈,进程由操作系统调度,不同进程通过进程间通信来通信,缺点:由于进程比较重量,占据独立的内存,所以开销比较大。优点:相对比较稳定安全
线程:共享堆,不共享栈。操作系统调度。线程是进程的一个实体,它是比进程更小的能独立运行的基本单位。优点:线程间通信主要通过共享内存,上下文切换很快,资源开销较少。缺点:但相比进程不够稳定容易丢失数据
协程:共享堆,不共享栈。协程由代码显示调度。轻量级线程,协程的调度完全由用户控制。直接操作栈则基本没有内核切换的开销,可以不加锁的访问全局变量,所以上下文的切换非常快
goroutine:本质上,goroutine 就是协程。不同的是,Golang 在 runtime、系统调用等多方面对goroutine 调度进行了封装和处理,当遇到长时间执行或者进行系统调用时,会主动把当前 goroutine 的CPU (P) 转让出去,让其他 goroutine 能被调度并执行,也就是 Golang 从语言层面支持了协程。Golang 的一大特色就是从语言层面原生支持协程,在函数或者方法前面加 go关键字就可创建一个协程。
资源利用最大化:一个应用程序一般对应一个进程,一个进程一般有一个主线程,还有若干个辅助线程,线程之间是平行运行的,在线程里面可以开启协程,让程序在特定的时间内运行。
其他方面比较:
1. 内存消耗方面
每个 goroutine (协程) 默认占用内存远比 Java 、C 的线程少。
goroutine:2KB
线程:8MB
2. 线程和 goroutine 切换调度开销方面
线程/goroutine 切换开销方面,goroutine 远比线程小
线程:涉及模式切换(从用户态切换到内核态)、16个寄存器、PC、SP...等寄存器的刷新等。
goroutine:只有三个寄存器的值修改 - PC / SP / DX.
2.孤儿进程,僵尸进程
一个电脑的进程号有限制的,每一个程序启动都会占用一个进程号
init(PID=1)称为孤儿福利院,操作系统中的PID号是有限的,如有子进程PID号无法正常回收,则会占用PID号
僵尸进程:
在子进程结束后,主进程没有正常结束, 子进程PID不会被回收。危害:致系统不能产生新的进程
若PID号满了,则无法创建新的进程
孤儿进程:
在子进程没有结束时,主进程没有“正常结束”, 子进程PID不会被回收。等子进程结束,由init孤儿院回收
在操作系统领域中,孤儿进程指的是在其父进程执行完成或被终止后仍继续运行的一类进程。这些孤儿进程将被init进程(进程号为1)所收养,并由init进程对它们完成状态收集工作
3.进程通讯,为什么共享存储区效率最高
进程可以直接读写内存,不需要任何数据等拷贝。
同一块物理内存被映射到A、B进程,实现资源共享
4.线程的栈在哪里分配
内存逃逸:决定分配到栈还是堆,分到堆堆就是逃逸。 堆需要gc垃圾回收,栈不需要gc。
决定是否逃逸到堆堆因素:
1.在其他地方(非局部)可能被引用
2.栈空间不足
3.动态分配
栈:局部变量、函数参数、返回地址等
堆:动态分配的内存
BSS段:未初始化或初值为0的全局变量和静态局部变量
数据段:已初始化且初值非0的全局变量和静态局部变量
代码段:可执行代码、字符串字面值、只读变量
选择了IT,必定终身学习