进程、线程和协程

高大强19 · · 617 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

这三个概念是很基础也很重要的概念:

1.进程挂靠在操作系统,操作系统会以进程为单位,分配系统资源(CPU时间片、内存等资源),进程是资源分配的最小单位。注意是资源分配哦,在内存里,有自己独立的地址空间和堆。

2.线程是调度和分配的基本单位,线程只能属于进程,进程至少有一个线程。

进程好比是道路,线程比喻成各条车道。这些线程(车道)之间依靠代码逻辑(交通灯)来控制运行,一旦代码逻辑有误,如死锁,多个线程竞争唯一资源,线程将陷入混乱。

线程车道之间谁先运行时未知的,只有线程刚好被分配到cpu时间片(交通灯变化)的那一刻才能知道。

3.协程,是比线程更加轻量级的存在,协程能够由程序控制,性能带来了提升。就是当出现长时间的I/O操作时,通过让出目前的协程调度,执行下一个任务的方式,来消除ContextSwitch上的开销。

子程序(函数)调用是通过栈实现的,线程就是执行了一个子程序。而协程的调用不同,它是可中断的,记录一个状态后,转而执行别的子程序,在适当的时候在返回来接着执行。

当出现IO阻塞的时候,由协程的调度器进行调度,通过将数据流立刻yield掉(主动让出),并且记录当前栈上的数据,阻塞完后立刻再通过线程恢复栈,并把阻塞的结果放到这个线程上去跑,这样看上去好像跟写同步代码没有任何差别,这整个流程可以称为coroutine,而跑在由coroutine负责调度的线程称为Fiber。比如Golang里的 go关键字其实就是负责开启一个Fiber,让func逻辑跑在上面。

由于协程的暂停完全由程序控制,发生在用户态上;而线程的阻塞状态是由操作系统内核来进行切换,发生在内核态上。

因此,协程的开销远远小于线程的开销,也就没有了ContextSwitch上的开销。

拓展:

传统的J2EE系统中,系统的吞吐能力取决于每个线程的操作耗时,如果线程很多的时候,会存在很多线程处于空闲状态(等待该线程执行完才能执行),造成了资源应用不彻底。最常见的例子:JDBC它是同步阻塞的。现阶段行业里的比较流行的解决方案之一是单线程加上异步回调。其代表派是node.js以及Java里的新秀Vert.x

参考:https://www.cnblogs.com/Survivalist/p/11527949.html

https://blog.csdn.net/daaikuaichuan/article/details/82951084


有疑问加站长微信联系(非本文作者)

本文来自:简书

感谢作者:高大强19

查看原文:进程、线程和协程

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

617 次点击  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传