进程、线程与协程


进程

进程是指在系统中正在运行的一个应用程序,是CPU的最小工作单元。

进程运行中的三种状态:就绪、运行、阻塞。创建和退出是描述产生和释放的状态。

在任务简单or偏向CPU密集型(计算多IO少)时,进程的CPU利用率较高。随着程序功能越来越复杂,常规的程序更加偏向IO密集型。但IO存在阻塞等待的特点,当一个程序获得了CPU的时间片由就绪态切换至运行态,往往因为长时间等待IO而进入阻塞态,在IO操作完成后进入就绪态,在下一次获得CPU时间片时才能完成。

无法即时完成的任务带来大量的上下文切换代价与时间代价。

    • 进程的上下文:当一个进程在执行时,CPU的所有寄存器中的值、进程的状态以及堆栈中的内容被称为该进程的上下文。
    • 上下文切换:当内核需要切换到另一个进程时,它需要保存当前进程的所有状态,即保存当前进程的上下文,以便在再次执行该进程时,能够得到切换时的状态并执行下去。

 

当人们开始思考使用更小的粒度提高进程单位时间的CPU利用率,线程应运而生。

线程

线程是CPU的最小执行单元(调度单元)。

进程作为线程的容器,按不同的功能,或想达到更高效率(如多个IO线程)的同一功能,可以考虑产生多个线程。

在CPU切换到本进程的时间段时,由于线程间共享进程的上下文,线程切换只需要切换线程的上下文,而不需要切换另一片内存或者寄存器资源,在功能并行执行的同时降低了开销。

    • 开更多的线程不会导致本进程得到更多CPU的青睐

进程才是CPU的最小作业单元(最小资源管理单元),开更多的线程不会导致本进程得到更多CPU的青睐,而是提高了CPU在本进程使用时间段的利用率。但是,本进程使用时间段的各线程优先级是用户可以自己设置的。

 

协程

虽然线程大幅的提高了CPU的效率,且能够设置一定的优先级,但是线程的资源片分配还是由CPU来管理的。

那么能不能人为管理线程的资源分配(切换)呢?协程在语言层面实现了这一点。

协程=微线程=纤程

如同一个进程可以有很多线程一样,一个线程可以有很多协程。

但是,协程不是被操作系统所管理的,没有改变CPU最小执行单元是线程,协程是完全由程序所控制的(用户态执行),不会产生上下文切换。

 

目前只有部分语言实现了协程

  1. python的yield/send,当协程执行到yield关键字时,会暂停在那一行,等到主线程调用send方法发送了数据,协程才会接到数据继续执行。
  2. Lua从5.0版本开始使用协程,通过扩展库coroutine来实现。
  3. Go语言对协程的实现非常强大而简洁,可以轻松创建成百上千个协程并发执行。
  4. Java语言并没有对协程的原生支持,但是某些开源框架模拟出了协程的功能,有兴趣的小伙伴可以看一看Kilim框架的源码:https://github.com/kilim/kilim


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM