- 进程,由OS来管理,每个进程都有自己独立的内存空间,进程之间通讯主要是通过信号传递的方式来实现的,实现方式有多种,信号量,管道,事件等,任何一种方式的通讯效率都需要过内核,导致通讯效率比较低.由于是独立的内存空间,所以上下文切换的时候需要保存当先调用栈的信息,cpu各寄存器的信息,虚拟内存,以及打开的相关句柄等信息,所以导致上下文切换的代价非常高,因此进程并不适合大量创建.
- 线程:也是由OS来管理的,一个进程可以拥有多个线程,但是其中每个线程会共享父进程像OS申请的资源,这个包括虚拟内存,文件等,由于是共享资源,所以创建线程所需要的系统资源占用比进程小很多,相应的可创建的线程数量也变得相对多很多.线程时间的的通讯除了可以使用进程之间通讯的方式以外还可以通过共享内存的方式进行通信,这个在java里面多个线程就可以通过一个共享的Queue来完成通讯,由于是在内存里面的访问,所以这个速度你完全可以想象到比通过内核要快很多.另外在调度方面还是由于内存是共享的,所以上下文切换的时候需要保存的东西就像对少一些,这样一来上下文的切换也变得高效,但是有一种情况上下文切换的效率和进程间切换差不多,那就是不同线程组时间的切换,你基本上可以认为一个线程组就是一个进程(效率上这么认为,实际上不是)
- 协程:上面提到的进程和线程都是由OS来控制其切换的,使用的是抢占式(why?自己查资料去).协程是用户层面的东东,他的切换是由用户自己来决定的,你可以想想用户创建了几个线程,然后每个线程都是循环按照指定的任务清单顺序完成不同的任务,当任务被堵塞的时候执行下一个任务,当恢复的时候再回来执行这个任务,任务之间的切换只需要保存每个任务的上下文内容,就像直接操作栈一样的,这样就完全没有内核切换的开销,所以上下文的切换非常快.另外协程还需要保证是非堵塞的且没有相互依赖,协程基本上不能同步通讯,多采用一步的消息通讯,效率比较高.比较具有代表性的是golang里面goroutine.
另外还有一个叫绿色线程的东东,这个东东比较少见,和协程的相似点是都不由OS控制调度,而是由用户自己来调度他,但是他的上下文切换和同步都更像线程