进程,线程,协程
1 什么是进程
进程是系统进行资源分配和调度的一个独立单位,是系统运行程序的基本单位,
1.1 进程的调度
所谓进程的调度算法,就是CPU所遵循的在什么时刻调用进程的规则,一般来说有以下几种:
先来先服务:哪个进程先来,CPU为哪个进程干活。这种调度方式有利于长作业,但是不利于短作业。
短作业优先:按照运行时间最短的顺序进行调度。这种虽然短作业能及时得到执行,但是长作业可能因为很久得不到cpu然后饿死。
优先级调度:按照每个进程的优先级进行排序调度。
时间片轮转:这个就类似于CPU的并发执行,对于每个作业都做一段时间然后切换到下一段,具体做多少时间这个需要看实际的作业。时间太短,那么进程间切换就太多;时间太长,那么有些作业就不能及时得到执行。
最短剩余时间优先:这个和短作业优先有点类似,每当新作业进来时,就会将新的和当前作业的剩余时间对比,如果新的较短,那么当前进程被挂起,去执行新的
1.2 进程间的通信
进程间为了保障健壮性,所以一个进程是不能随意进入其他进程去获取状态的,因此进程间的通信往往要依赖于第三方空间,进程间的通信方式有以下几种:
管道通信:
管道通信是操作系统在内核划分出一块缓冲区,而进程通过管道通信,实际上就是与这个缓冲区进行交互。管道通信很明显,优点在于:直截了当,同步(管道会控制满与空时的读写操作),效率高(内部直接写数据就行了,不需要其他包装);缺点在于:缓冲区大小有限;写的数据格式单一,如果同时有大量数据写入,管道是不会将数据进行分开的(即多个消息的数据会直接堆在一起)
消息队列通信:
这个就是利用额外的消息队列进行通信,优点:能进行异步通信,由内核管理传输可靠,并且不只是端对端,而是有多种通信模式,包括订阅发布等;缺点也很明显:消息队列是需要额外维护的,需要性能开销;并且需要额外设置同步机制来确保通信顺序
共享内存通信
共享内存通信就是划出一份内存空间:优点,传输很快,并且效率很高(这块内存空间比较特殊,进程可以直接读写这一块内存而不需要进行数据的拷贝,从而大大提高效率);缺点:也需要同步,管理也比较复杂,大小也有限。
信号量通信
这个一般不用来通信,就像一个许可证,是用来配合其他通信方式实现同步的
信号通信
一个进程向另一个进程发送信号通知,当然这种信号本身是比较简单的通信,不需要什么同步机制,而且携带消息也很少,基本上就是一个编号,进程在接收到信号之后会通过信号处理函数去对信号进行处理,如果没有该信号对应的函数,就会采取默认的信号动作
socket通信
这个通信比较特殊,已经到了不同主机端口互相通信的级别了,具体的话可以直接去看计算机网络通信部分。优缺点也很明显:优点,功能多、灵活性高、跨网络通信,缺点:复杂度也很高、并且需要额外的性能开销。
2 什么是线程
由于进程之间的创建切换销毁开销都比较大,因此人们创建了一种轻量级的进程,即线程,线程被设计为进程的一个执行路径,线程是CPU调度的基本单位,同一进程内的线程会共享进程的堆和方法区资源,因此在线程切换的成本上要远低于进程。可以将线程成为轻量级的进程。
线程共享进程的堆和方法区,但是实际上也有自己的私有资源,即程序计数器,虚拟机栈和本地方法栈。
程序计数器主要是用来记录现在读到哪个指令了,方便自身的运行以及线程切换。
虚拟机栈的作用是保证线程执行方法时,方法内部的局部变量不会被其他线程所访问到,而本地方法栈则为所用到的native方法服务(每个线程执行的本地方法可能不一样,因此也需要私有)
3 线程与进程的区别
1 进程是系统资源分配的基本单位,线程是CPU分配的基本单位
2 一个程序至少有一个进程,一个进程至少有一个线程
3 进程的地址空间独立,不共享资源,进程切换开销大;同一个进程内的线程共享地址空间,线程切换开销小
4 进程健壮性高
5 线程较为轻量级,多线程程序并发性高
4 什么是协程
协程是比线程更加轻量级的存在,协程与进程线程最大的区别就是,它不被操作系统内核管,它是由用户通过程序自己去控制的,避免了无意义的调度,在用户态执行,也因此程序员需要自己去设定如何调度。线程的阻塞状态是由操作系统内核来进行来回切换的,而协程的阻塞是由用户自己控制的,因此协程的开销要远小于线程。
但是协程由于是用同一个线程去执行的,也因此不具有使用多CPU的能力,在实际操作中只能去串行执行