多线程模型浅谈

优质博文:IT-BLOG-CN

笔者近期在维护的项目中发现了一些比较随机的问题,时有时无的,排查之后发现是使用多线程导致的,恍然之下研究了下多线程的底层模型相关知识,现不大家简要分享下。

一个程序进程可包含多个线程,线程为进程中代码的不同执行路线。从实现方式上划分,线程有两种类型:“用户级线程”和“内核级线程”。

而线程模型就是根据内核线程和用户线程之间的映射关系区分出来的。内核线程指需要内核的参与,由内核完成线程的调度。其依赖于操作系统核心,由内核的内部需求进行创建和撤销。

内核维护进程及线程的上下文信息以及线程切换。内核线程的线程表位于内核中,包括了线程控制快(TCB),一旦线程阻塞,内核会从当前或者其他进程中重新选择一个线程保证程序的执行。用户线程指不需要内核支持而在用户程序中实现的线程,其不依赖于操作系统核心,应用进程利用线程库提供创建、同步、调度和管理线程
的函数来控制用户线程。那么根据这两者之间的映射关系,有以下三种模型:

1:1模型:用户线程不内核线程内核线程是一对一(1 : 1)的映射模型,也就是每一个用户线程绑定一个实际的内核线程,而线程的调度则完全交付给操作系统内核去做,应用程序对线程的创建、终止以及同步都基于内核提供的系统调用来完成。

大部分编程语言的线程库比如Java的java.lang.Thread是对操作系统的线程(内核级线程)的一层封装,创建出来的每个线程不一个独立的内核线程静态绑定,因此其调度完全由操作系统内核调度器去做。所以java线程如果出现死锁,或者饥饿会导致系统很大开销,因为他使用native调用系统调用,fork出来的内核线程。

这种模型的优势和劣势同样明显:优势是实现简单,直接借助操作系统内核的线程以及调度器,所以CPU可以快速切换调度线程,于是多个线程可以同时运行,因此相较于用户级线程模型它真正做到了并行处理;但它的劣势是,由于直接借助了操作系统内核来创建、销毁和以及多个线程之间的上下文切换和调度,因此资源成本大幅上
涨,且对性能影响很大。

N:1模型:用户线程不内核线程是多对一(N : 1)的映射模型,多个用户线程的一般从属于单个进程并且多线程的调度是由用户自己的线程库来完成,线程的创建、销毁以及多线程之间的卋调等操作都是由用户自己的线程库来负责而无项借助系统调用来实现。

一个进程中所有创建的线程都只和同一个内核线程在运行时动态绑定,也就是说,操作系统只知道用户进程而对其中的线程是无感知的,内核的所有调度都是基于用户进程。由于线程调度是在用户层面完成的,也就是相较于内核调度不需要让CPU在用户态和内核态之间切换,这种实现方式相比内核级线程可以做的很轻量级,对系统资
源的消耗会小很多,因此可以创建的线程数量与上下文切换所花费的代价也会小得多。

但该模型有个原罪:当多线程并发执行时,如果其中一个线程执行IO操作时,内核接管这个操作,如果IO阻塞,用户态的其他线程都会被阻塞,因为这些线程都对应同一个内核调度实体。

在多处理器机器上,内核不知道用户态有这些线程,无法把它们调度到其他处理器,也无法通过优先级来调度。这对线程的使用是没有意义的!

N:M混合模型: 多路复用多个用户级线程到同样数量或更少数量的内核线程。内核线程的数量可能不特定应用程序或特定机器有关(应用程序在多处理器上比在单处理器上可能分配到更多数量的线程)。

混合模型是博采众长之后的产物,充分吸收前两种线程模型的优点且尽量规避它们的缺点。在此模型下,用户线程不内核线程是多对多(N : M)的映射模型:

首先,区别于用户级线程模型,混合模型中的一个进程可以不多个内核线程内核线程关联,于是进程内的多个线程可以绑定不同的内核线程,这点和内核级线程模型相似;

其次,又区别于内核级线程模型,它的进程里的所有线程并不与内核线程一一绑定,而是可以动态绑定同一个内核线程,当某个内核线程因为其绑定的线程的阻塞操作被内核调度出CPU时,其关联的进程中其余用户线程可以重新与其他内核线程绑定运行。

所以,混合模型既不是用户级线程模型那种完全靠自己调度的也不是内核级线程模型完全靠操作系统调度的,而是中间态(自身调度不系统调度卋同巟作),因为这种模型的高度复杂性,而且并不是所有操作系统都支持多对多的混合模型,操作系统内核开发者一般不会使用(Linux的Native POSIXThreads Library就因为其复杂性pass掉了这种实现方式,但是 Solaris JDK 又实现了在Solaris 下的混合多对多模型),所以更多时候是作为第三方库的形式出现。

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/579745.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

统计建模——模型——python为例

统计建模涵盖了众多数学模型和分析方法,这些模型和方法被广泛应用于数据分析、预测、推断、分类、聚类等任务中。下面列举了一些常见的统计建模方法及其具体应用方式: 目录 1.线性回归模型: ----python实现线性回归模型 -------使用NumPy…

牛客网刷题 | BC66 牛牛的通勤

目前主要分为三个专栏,后续还会添加: 专栏如下: C语言刷题解析 C语言系列文章 我的成长经历 感谢阅读! 初来乍到,如有错误请指出,感谢! 描述 牛牛的通勤路上有两…

yolov8旋转目标检测输出的角度转化为适合机械爪抓取的角度

1. 机械爪抓取时旋转的角度定义 以X轴正方向(右)为零度方向,角度取值范围[-90,90)。 确认角度的方法: 逆时针旋转X轴,X轴碰到矩形框长边时旋转过的角度记为angleX: 1.如果angleX小于90&#xf…

udp/tcp错误总结

udp tcp——多进程 tcp——多线程 tcp——线程池 tcp——守护进程 🎆udp  ✨pthread_create 错误总结  ✨LockGuard错误总结  ✨服务端需要写成多线程  ✨客户端也需要写成多线程  ✨多线程调试工具 🎆tcp  ✨tcp独有调试工具——telnet  ✨Threa…

Python的历史演变与作用

目录 1.概述 2.起源 3.发展阶段 4.Python 3的诞生 5.现状与未来 6.Python的作用 6.1.Web开发 6.2.数据科学与人工智能 ​​​​​​​6.3.自动化与脚本编程 ​​​​​​​6.4.教育与学习 ​​​​​​​6.5.其他领域 7.结语 1.概述 Python,一门富有表…

DSP开发实战教程-国产DSP替代进口TI DSP的使用技巧

1.替换CCS安装路径下的Flash.out文件 找到各自CCS的安装路径: D:\ti\ccs1230\ccs\ccs_base\c2000\flashAlgorithms 复制进芯电子国产DSP官网提供的配置文件 下载链接:https://mp.csdn.net/mp_download/manage/download/UpDetailed 2.替换原有文件 3.…

Thinkphp--in-sqlinjection

一、漏洞原理 在 Builder 类的 parseData 方法中&#xff0c;由于程序没有对数据进行很好的过滤&#xff0c;将数据拼接进 SQL 语句&#xff0c;导致 SQL注入漏洞 的产生。 影响版本 5.0.13<ThinkPHP<5.0.15 5.1.0<ThinkPHP<5.1.5 在相应的文件夹位置打开终端…

记录如何用php做一个网站访问计数器的方法

简介 创建一个简单的网站访问计数器涉及到几个步骤&#xff0c;包括创建一个用于存储访问次数的文件或数据库表&#xff0c;以及编写PHP脚本来增加计数和显示当前的访问次数。 方法 以下是使用文件存储访问次数的基本步骤&#xff1a; 创建一个文本文件来存储计数&#xff1a…

.NET 检测地址/主机/域名是否正常

&#x1f331;PING 地址/主机名/域名 /// <summary>/// PING/// </summary>/// <param name"ip">ip</param>/// <returns></returns>public static bool PingIp(string ip){System.Net.NetworkInformation.Ping p new System.N…

Codeforces Round 941 (Div. 1) E. Connected Cubes(构造)

题目 思路来源 官方题解 题解 可以看下官方题解的7张图&#xff0c;还是比较清晰的&#xff0c;这里直接粘贴一下 来源&#xff1a;Codeforces Round #941 (Div. 1, Div. 2) Editorial - Codeforces &#xff08;1&#xff09;原来的图 &#xff08;2&#xff09;对于偶数行…

牛客NC376 变回文串的最少插入次数【困难 动态规划,回文 C++/Java/Go/PHP 高频】力扣同一道题1312

题目 题目链接&#xff1a; https://www.nowcoder.com/practice/bae2652b4db04a438368238498e4c13e https://leetcode.cn/problems/minimum-insertion-steps-to-make-a-string-palindrome/description/ 思路 参考答案C class Solution {public:/*** 代码中的类名、方法名、参…

炒股自动化:券商官方,散户可用,查询订单状态API如何用?

券商官方的接口&#xff0c;个人账户可申请&#xff0c;入金门槛低&#xff0c;接入文档完善&#xff0c;技术支持好的&#xff0c;经过我们筛选后&#xff0c;只有一家符合 会编程&#xff0c;有基础&#xff0c;只是需要API接口的朋友不用看这些&#xff0c;不会写程序的朋友…

nacos-redis-springboot

新项目 准备工作 nacos 版本 2.0.3 redis 最终版本说明 springcloud-alibaba&#xff1a;2.2.7RELEASE springcloud&#xff1a;Hoxton.SR12 springboot&#xff1a;2.3.12.RELEASE Nacos&#xff1a;2.0.3 步骤 启动nacos和redis 准备nacos配置文件 server: port…

avl excite python二次开发1--python解释器需用内置解释器aws_cmd

avl excite python二次开发1--python解释器需用内置解释器aws_cmd 1、python解释器问题1.1、用外置python解释器&#xff0c;import WSInterface会失败(WSInterface.pyd)1.2、用内置解释器aws_cmd运行py脚本1.3 用内置解释器aws_python执行脚本三级目录 1、python解释器问题 1…

ssm项目后端如何导出war及前端如何导出静态资源

后端如何导出war包 后端工具&#xff1a;IDEA 2020.1.3 运行我们编写工具maven里面的package 运行成功的日志 我们运行完&#xff0c;会生成一个target文件夹&#xff0c;在这个文件夹里面找到war包即可 前端如何导出静态资源 使用工具&#xff1a;WebStorm 2020.1.3 打开左…

xLua详解

目录 环境准备xLua导入 C#调用LuaLua解析器Lua文件加载重定向Lua解析管理器全局变量的获取全局函数的获取List和Dictionary映射table类映射table接口映射tableLuaTable映射table Lua调用C#准备工作Lua使用C#类Lua调用C#枚举Lua使用C# 数组 List 字典数组List字典 Lua使用C#扩展…

读天才与算法:人脑与AI的数学思维笔记12_数学的艺术

1. 数学 1.1. 灵光乍现&#xff0c;从来都是厚积薄发 1.1.1. 亨利庞加莱&#xff08;Henri Poincar&#xff09; 1.2. 数学的起源可以追溯到人类试图理解自己所生活的环境&#xff0c;预测接下来会发生什么&#xff0c;从而使我们更加适应环境&#xff0c;并选择对我们有利的…

Python-VBA函数之旅-map函数

目录 一、map函数的常见应用场景 二、map函数使用注意事项 三、如何用好map函数&#xff1f; 1、map函数&#xff1a; 1-1、Python&#xff1a; 1-2、VBA&#xff1a; 2、推荐阅读&#xff1a; 个人主页&#xff1a;神奇夜光杯-CSDN博客 一、map函数的常见应用场景 ma…

Jammy@Jetson Orin - Tensorflow Keras Get Started: Concept

JammyJetson Orin - Tensorflow & Keras Get Started: Concept 1. 源由2. 模型2.1 推理流程2.1.1 获取图像2.1.2 算法识别2.1.3 判断决策 2.2 理想情况2.2.1 多因素输入2.2.2 理想识别概率 2.3 学习过程2.3.1 标记训练集2.3.2 损失函数2.3.3 训练网络2.3.4 渐进方法 3. 总…

使用Docker部署Jupyter Notebook并结合花生壳的内网穿透实现远程访问(详文)

一、前言 本文主要介绍如何利用宝塔面板中的Docker 3.9.3管理器,使用Docker本地部署Jupyter Notebook,并结合花生壳内网穿透工具实现任意浏览器公网远程访问Jupyter登录界面。 安装完成后在宝塔面板中图例 Jupyter Notebook是一个交互式笔记本,支持运行40多种编程语言。…
最新文章