[转帖]进程 线程和 协程

进程,线程 · 浏览次数 : 0

小编点评

**内核态线程** * 概念清晰,容易开发 * 线程切换的时机由操作系统决定,抢占式 * 线程上下文保存/载入成本高 * 效率低,线程数量多时,线程切换开销甚至能超过业务代码 **用户态线程** * 线程切换的时机由用户代码完全控制 * 线程上下文保存/载入成本低 * 效率高,线程数量多时,用户态线程可以并行运行 * 每个用户态线程都是一个独立的单线程进程

正文

作者:ScratchLab
链接:https://www.zhihu.com/question/308641794/answer/2867920715
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

线程有两种实现方式:内核态线程和用户态线程。早期,内核态线程由于概念清晰,对开发者友好,在与用户态线程的竞争中胜出。但随着互联网的发展,用户态线程凭借其线程切换成本低、竞态少等特点重新回归开发者视野,并逐步发展成最新的并发模型--协程。下面我们从线程切换和竞态两个方面介绍一下内核态线程和用户态线程。从线程切换的角度来讲,进程与线程基本原理是一样的。下图展示了内核态线程切换的一个大概的过程:<img src="https://pic1.zhimg.com/50/v2-170cedfa1203204c13fafc91283bd031_720w.jpg?source=1940ef5c" data-caption="" data-size="normal" data-rawwidth="467" data-rawheight="501" class="origin_image zh-lightbox-thumb" width="467" data-original="https://pic1.zhimg.com/v2-170cedfa1203204c13fafc91283bd031_r.jpg?source=1940ef5c"/>当前时刻,线程A正在运行。此时,来了一个时钟中断,系统由ring3的线程A跳转到ring0的时钟中断handler中。当handler认为需要切换线程时,会将线程A的上下文保存到线程A的控制块中。然后,handler根据调度算法从就绪线程中选择一个来运行,假设handler选择了线程F来运行。handler会将线程F的上下文从其控制块中载入到当前线程。完成上下文保存/载入工作后,handler退出,并跳转到ring3。此时,ring3中运行的就是线程F了。从上述流程我们可以发现,内核态线程有以下特点:线程切换的时机由操作系统决定(抢占式),线程无法对切换时机做任何假设。因此,多线程程序开发时必须考虑竞态线程切换时涉及到特权级的跳转和线程上下文的保存/载入这就造成了内核态线程切换时的成本非常高,线程数量多时,线程切换的开销甚至能超过业务代码。下面,我们看一下用户态线程的切换过程。下图展示了用户态线程切换的一个大致过程:<img src="https://picx.zhimg.com/50/v2-1fe9d8624b94078935205e93d828dca6_720w.jpg?source=1940ef5c" data-caption="" data-size="normal" data-rawwidth="456" data-rawheight="368" class="origin_image zh-lightbox-thumb" width="456" data-original="https://picx.zhimg.com/v2-1fe9d8624b94078935205e93d828dca6_r.jpg?source=1940ef5c"/>当前时刻,线程A正在运行。线程A运行一段时间后主动退出,将其上下文保存到线程A的控制块中。然后,线程A根据用户代码从其他线程中选择一个来运行。假设用户代码要求线程A退出后线程F继续运行。线程A会将的线程F的上下文载入到当前线程中,并跳转到线程F的代码中运行。各用户态线程不断的运行、退出,形成这样一个序列:A线程运行A线程退出,选择F来运行F线程运行F线程退出,选择D来运行D线程运行D线程退出,选择E来运行...A线程运行A线程退出,选择B来运行从以上介绍中我们可以看到,没有了时钟中断,某个线程运行时无法被强制退出,只有主动退出,其他线程才有运行机会。用户态线程的调度就依靠各线程在合适的时机主动退出,让其他线程获得运行机会来进行。各用户态线程彼此协作,推动程序的运行,因此,用户态线程又称作协程。从上述流程我们可以看出,用户态线程有以下特点:各用户态线程本质上是在一个单线程进程上执行的,线程调度的时机由用户代码完全控制,因此不用考虑竞态线程切换过程不涉及特权级的跳转线程切换时也涉及到上下文的保存/载入,但是各用户态线程是在一个单线程进程上运行的,可以共享许多数据,因此用户态线程上下文的数据量远远小于内核态线程上下文从以上特点我们可以看到,用户态线程切换的开销非常低,且系统不会限制用户态线程的数量,非常适合高并发。

与[转帖]进程 线程和 协程相似的内容:

[转帖]进程 线程和 协程

作者:ScratchLab链接:https://www.zhihu.com/question/308641794/answer/2867920715来源:知乎著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。 线程有两种实现方式:内核态线程和用户态线程。早期,内核态线程由于概念清晰

[转帖]Redis如何绑定CPU

文章系转载,便于分类和归纳,源文地址:https://www.yisu.com/zixun/672271.html 绑定 CPU Redis 6.0 开始支持绑定 CPU,可以有效减少线程上下文切换。 CPU 亲和性(CPU Affinity)是一种调度属性,它将一个进程或线程,「绑定」到一个或一组

[转帖]Redis如何绑定CPU

文章系转载,便于分类和归纳,源文地址:https://www.yisu.com/zixun/672271.html 绑定 CPU Redis 6.0 开始支持绑定 CPU,可以有效减少线程上下文切换。 CPU 亲和性(CPU Affinity)是一种调度属性,它将一个进程或线程,「绑定」到一个或一组

[转帖]网卡bonding模式 - bond0、1、4配置

网卡bonding简介 网卡绑定就是把多张物理网卡通过软件虚拟成一个虚拟的网卡,配置完毕后,所有的物理网卡的ip和mac将会变成相同的。多网卡同时工作可以提高网络速度,还可以实现网卡的负载均衡、冗余。 bonding模式 1 round-robin(mode=0) 轮转策略,轮流在每一个slave网

【转帖】网卡bonding模式 - bond0、1、4配置

网卡bonding简介 网卡绑定就是把多张物理网卡通过软件虚拟成一个虚拟的网卡,配置完毕后,所有的物理网卡的ip和mac将会变成相同的。多网卡同时工作可以提高网络速度,还可以实现网卡的负载均衡、冗余。 bonding模式 1 round-robin(mode=0) 轮转策略,轮流在每一个slave网

[转帖]linux进程、线程与cpu的亲和性(affinity)

https://www.cnblogs.com/wenqiang/p/6049978.html 最近的工作中对性能的要求比较高,下面简单做一下总结: 一、什么是cpu亲和性(affinity) CPU的亲和性, 就是进程要在指定的 CPU 上尽量长时间地运行而不被迁移到其他处理器,也称为CPU关联性

[转帖]如何快速查看进程/子线程堆栈

背景:分析现网问题时,有时需要快速查看某个进程/子线程堆栈调用,便于进一步分析问题,现提供几种不同获取进程堆栈方法。 实现方法: 1.使用gdb attach 调试进程,使用gdb相关cmd调试进程 # gdb -p pid 进入gdb后,可通过 (gdb)bt 查看主进程堆栈 (gdb)info

[转帖]总结:协程与线程

一、介绍 本文主要梳理下进程,线程,协程的概念、区别以及使用场景的选择。 二、进程 我们知道,一切的软件都是跑在操作系统上,真正用来干活 (计算) 的是 CPU。早期的操作系统每个程序就是一个进程,知道一个程序运行完,才能进行下一个进程,就是 “单进程时代”。一切的程序只能串行发生。 早期的单进程操

[转帖]深入理解同步机制---内核自旋锁

https://switch-router.gitee.io/blog/spinlock/ 进程(线程)间的同步机制是面试时的常见问题,所以准备用一个系列来好好整理下用户态与内核态的各种同步机制。本文就以内核空间的一种基础同步机制—自旋锁开始好了 自旋锁是什么 自旋锁就是一个二状态的原子(atomi

[转帖]内核同步原语

https://blog.mygraphql.com/zh/notes/low-tec/kernel/5-sync/synchronizeation-primitives/ 什么是同步原语 共享内存,多进程/线程的运行期设计模式已成主流的今天,你有好奇一下,进程/线程间的怎么同步的吗?大部分人知道,