理解计算机系统_并发编程(10)_线程(七):基于预线程化的并发服务器
前言
以<深入理解计算机系统>(以下称“本书”)内容为基础,对程序的整个过程进行梳理。本书内容对整个计算机系统做了系统性导引,每部分内容都是单独的一门课.学习深度根据自己需要来定
引入
接续理解计算机系统_并发编程(9)_线程(六):读者-写者问题-CSDN博客,对应本书P708开始内容
线程的进一步思考
前面提到线程的抽象:共享数据,共享函数体,内核自动调度.似乎还不能概括线程的特点,笔者用一个更简洁的观点来看待线程:线程是一个特殊的函数. 并发执行的n个相同函数.据此做一些推导:
1>操作相同数据.通过全局变量和局部静态变量来实现各个线程(函数)之间的数据共享.
2>返回相同类型的数据.在有返回值的前提下,n个线程将自动生成一个n个元素组成的数据集合(生产者-消费者模型).关于这里有一点说明:在理解计算机系统_并发编程(8)_线程(五):生产者-消费者问题_计算机学科中的生产者消费者是什么-CSDN博客
贴中,提到了缓冲区内的数据是有序的,数据结构选用了队列.其实有序无序不是强制的,但考虑到如果是无序的,缓冲区内的数据存在不被访问的风险---一直用不上,所以设置成有序.另外在本贴中,在缓冲区里放置的是文件描述符,也必须设成有序,否则有客户端发来的连接会一直连接不上的后果.
=============================内容分割线↓===================================
单任务线程化
在遇到多核CPU时,将单个任务(函数)线程化---一个函数分解成多个线程,可能会提高效率.
注意:基于笔者的一个设想,有没有效果必须经验证.
假设一个结构里有3个int变量,用单任务的写法
//单任务
/*结构定义*/
struct Demo{int pa1;int pa2;int pa3;
}
/*单任务定义,为简便硬编码*/
void fun(struct Demo* dep){dep->pa1=1;dep->pa2=2;dep->pa3=3;
}
/*主函数调用*/
int main(void){struct Demo de;fun(&de);
}
以下是多线程写法
//单个任务多线程完成
struct Demo{int pa1;int pa2;int pa3;
}
void *thread(void *vargp);
struct Demo de;
pthread_t tid1,tid2,tid3;int main(){Pthread_create(&tid1,NULL,thread,&de); //生成对等线程1Pthread_create(&tid2,NULL,thread,&de); //生成对等线程2Pthread_create(&tid3,NULL,thread,&de); //生成对等线程3Pthread_join(tid1,NULL); //等待对等线程终止Pthread_join(tid2,NULL); //等待对等线程终止Pthread_join(tid3,NULL); //等待对等线程终止exit(0); //终止当前进程中所有线程
}void *thread(void *vargp){struct Demo* de=(struct Demo*)vargp;if(pthread_self(void)=tid1){de->pa1=1;return NULL;};if(pthread_self(void)=tid2){de->pa2=2;return NULL;};if(pthread_self(void)=tid3){de->pa2=3;return NULL;};
}
多线程的写法显得"生硬"(未经过验证,可能会有bug),只说思路
两者对比感觉到因为共享的原因,多线程所需的堆区内存会比单任务大
=============================内容分割线↑===================================
信号量
信号量的操作在理解计算机系统_并发编程(7)_线程(四):信号量和互斥锁-CSDN博客有过说明,信号量的作用需要做个概括.信号量的作用是"锁",一是互斥锁,二是资源锁.锁的是线程的个数.
互斥锁:当信号初始化为1,采用P(v)时,进入线程(函数)的线程个数被限制为1,只有当前线程可以访问共享变量. 资源锁:当信号初始化为n,进入线程(函数)的线程个数被限制为n,可以有n个线程进入,产生n个数据(限制缓冲区的数据个数为n).
一句话概括:信号量提供锁,控制线程个数
信号量的延伸使用
可以作为一个点深入思考信号量的其他用法,比如读者-写者模式中怎样限制读者的个数.
基于预线程化的并发服务器
本书P708:在图12-14所示的并发服务器中,我们为每一个新客户端创建了一个新线程.这种方法的缺点是我们为每一个新客户端创建一个新线程,导致不小的代价.一个基于预线程化的服务器试图通过使用如图12-27所示的生产者-消费者模型来降低这种开销.
服务器是由一个主线程和一组工作者线程构成的.主线程不断地接受来自客户端的连接请求,并将得到的连接描述符放在一个有限缓冲区中.每一个工作者线程反复地从共享缓冲区中取出描述符,为客户端服务,然后等待下一个描述符.
---解读:一个客户端创建一个线程,导致不小的代价,如果没有亲身体验感觉不出来.既然书上介绍有更好的方法跟着走.
代码思路
首先,不能为了读代码而读.学习别人代码的目的是编程的思路和代码的组织.但同时一定要有自己的思考.所以,在读代码之前,先想想如果是自己来写,应该怎么思考怎么写?
1>从工具入手.摩天大厦不是一步建成的,得先打地基,再造出梁柱和铺楼板,编程要先看一下手里有什么工具,
a.SBUF的程序包---用于生产者-消费者模式,建立一个符合要求的缓冲区,一个数据队列.
b.一个基于线程的并发服务器.他的核心是生成connfd文件描述符,并根据connfd传输数据.
两者结合,构建一个文件描述符队列的缓冲区.文件描述符本身是int类型,和SBUF内的队列数据元素类型一致,可不修改直接用.
2>从数据入手.程序的一切都围绕着数据.这里的"显式"数据是缓冲区,推出的内容和第1条一致.
代码解读
本书P709主程序echoservert-pre.c
第24行:初始化缓冲区
第25,26行:建立NTHREADS个线程,线程函数:第35行~第42行处理文件描述符connfd
第31行,文件描述符添加进缓冲区
第39行,消费者线程取出文件描述符.
本书P710程序echo-cnt.c
第17,18行:初始化线程,每个线程执行到这里需要先初始化
第8行,初始化信号量mutex,作互斥锁.由初始化线程函数(第18行)调用
第22行和第26行:保护共享变量byte_cnt
一个小问题:
echoservert-pre.c的预处理文件中应有#include "echo-cnt.h",本书省略了echo-cnt.h的内容
小结
线程内容的一点思考和延伸,
"基于预线程化的并发服务器"代码的思路和解读.
不管是写函数,写一个包,或者建立一段程序,思路都是值得反复研究的,多看别人的代码多理解是个不错的切入点.
相关文章:

理解计算机系统_并发编程(10)_线程(七):基于预线程化的并发服务器
前言 以<深入理解计算机系统>(以下称“本书”)内容为基础,对程序的整个过程进行梳理。本书内容对整个计算机系统做了系统性导引,每部分内容都是单独的一门课.学习深度根据自己需要来定 引入 接续理解计算机系统_并发编程(9)_线程(六):读者-写者问题-…...

身份认证: JWT和Session是什么?
一、为什么需要临时凭证? 系统面临三个核心约束: 唯一鉴权方式只有(账号,密码) 服务端不记录请求状态,服务端不知道用户已登录了 避免重复传输敏感信息,不能每次都携带(账号,密码…...
OpenFOAM 字典系统与求解器配置解析机制
文章目录 OpenFOAM 字典系统与求解器配置解析机制字典系统的基本结构配置文件解析流程字典实现细节1. 字典存储结构2. 条目类型3. 令牌系统4. 解析过程 典型配置文件示例解析字典访问机制高级特性性能考虑 OpenFOAM 字典系统与求解器配置解析机制 OpenFOAM 使用一套独特的字典…...

机器学习中的多GPU训练模式
文章目录 一、数据并行(Data Parallelism)二、模型并行(Model Parallelism)1. 模型并行2. 张量并行(Tensor Parallelism) 三、流水线并行(Pipeline Parallelism)四、混合并行&#x…...

TPAMI 2025 | CEM:使用因果效应图解释底层视觉模型
底层视觉可解释性专题:https://x-lowlevel-vision.github.io/ 论文:https://arxiv.org/abs/2407.19789 代码:https://github.com/J-FHu/CEM 动机 在底层视觉领域,深度学习模型虽极大提升了任务性能,但其内部运行机…...
小红书文章内容提取免费API接口教程
接口简介: 提取指定小红书文章内容。本接口仅做内容提取,未经作者授权请勿转载。 请求地址: https://cn.apihz.cn/api/caiji/xiaohongshu.php 请求方式: POST或GET。 请求参数: 【名称】【参数】【必填】【说明】 【…...

Halcon 图像预处理②
非线性图像分段变化: 先窗体打开图片 对数非线性变化: 结果图像的亮度/对比度显著增加 log_image(Image,LogImag1,e) 参数1:输入图像 参数2: 输出图像 参数3:底数 log_image(Image,LogImage2,0.1) 图像结果亮度和…...

20250526-C++基础-函数指针
C基础-函数指针 函数指针,顾名思义就是指向函数的指针,用一个变量来存储函数的地址,可以通过这个变量(指针)间接访问函数。(可以把函数指针名看作函数名来进行函数调用)。代码及说明如下&#…...

软考 系统架构设计师系列知识点之杂项集萃(73)
接前一篇文章:软考 系统架构设计师系列知识点之杂项集萃(72) 第126题 可一次性编程的只读存储器是( )。 A. ROM B. PROM C. EPROM D. EEPROM 正确答案:B。 解析: ROM:出厂时已编程,用户无…...
大模型训练中的GPU作用解析
📌 友情提示: 本文内容由银河易创AI(https://ai.eaigx.com)创作平台的gpt-4-turbo模型辅助完成,旨在提供技术参考与灵感启发。文中观点或代码示例需结合实际情况验证,建议读者通过官方文档或实践进一步确认…...
Flutter Web 3.0革命:用WebGPU实现浏览器端实时光追渲染,性能提升300%
一、WebGPU为何是图形渲染的未来? 1. 传统WebGL的致命瓶颈 // WebGL 2.0绘制调用示例(每秒帧率<45) gl.drawElements(gl.TRIANGLES, vertexCount, gl.UNSIGNED_SHORT, 0); 性能对比表: 场景WebGL 2.0WebGPU三角形绘制速率…...

DeepSeek-V3-0526乍现
DeepSeek-V3-0526 可能是 DeepSeek 最新发布的模型版本,相较于之前的 DeepSeek-V3-0324,它在代码能力、推理性能和本地部署方面有了进一步提升。以下是关于该版本的主要信息: - DeepSeek-V3-0526 在多项基准测试中表现优异,性能…...
Java设计模式之观察者模式:从基础到高级的全面解析
文章目录 一、观察者模式基础概念1.1 什么是观察者模式?1.2 观察者模式的四大角色1.3 观察者模式类图二、观察者模式实现步骤2.1 基础实现步骤2.2 详细代码实现第一步:定义主题接口第二步:定义观察者接口第三步:创建具体主题第四步:创建具体观察者第五步:客户端使用三、观…...
C/C++---类型转换运算符
在C中,类型转换运算符(Type Conversion Operator)允许类对象在需要时自动转换为其他类型。这是一种特殊的成员函数,能够增强类的灵活性和交互性。 1. 基本语法 类型转换运算符的声明格式为: operator 目标类型() co…...

STM32 I2C 通信协议
1、原理 1、硬件电路 一主多从,单片机作为总线主机 SDA:数据线 SCL:时钟线 主机对SCL线完全控制,从机只能读取;在空闲状态下,主机可以主动发起对SDA的控制,只有在从机发送数据和从机应答的时…...

【后端高阶面经:Elasticsearch篇】38、Elasticsearch 高可用架构解析:分片容灾、Translog 调优与双集群
一、高可用架构核心:节点角色与分布式设计 (一)节点角色精细化划分 1. 四大核心节点类型 节点类型核心职责资源配置建议典型部署数量主节点(Master)集群元数据管理(索引创建、分片分配、节点选举)CPU≥4核,内存≥16GB,禁用数据存储3-5个(奇数)数据节点(Data)存储…...

5月26日复盘-自注意力机制
5月26日复盘 一、自注意力机制 Self-Attention Mechanism,自注意力机制,用于捕捉序列数据内部依赖关系的关键技术。它在NLP和CV中非常重要,尤其是Transformer。 1. 产生背景 自注意力机制的产生与序列建模任务(如机器翻译、文…...
*HTML `<script>` 标签中的核心属性解析:掌控脚本加载与执行的艺术
HTML <script> 标签中的核心属性:掌控脚本加载与执行的艺术 在网页开发中,<script> 标签是 JavaScript 的“入口”。它不仅决定了脚本如何加载和执行,还深刻影响着页面性能、安全性和跨域策略。本文将深入解析 <script> 标…...

聊一聊接口测试如何设计有效的错误响应测试用例
目录 一、 覆盖常见的错误场景 a. 输入验证错误 b. 认证与权限错误 c. 资源操作错误 d. 业务逻辑错误 e. 服务端错误 二、设计测试用例的关键原则 a. 明确的错误信息 b. 正确的 HTTP 状态码 c. 幂等性处理 d. 安全性与敏感信息 三、测试用例设计模板 四、工具与自…...
记忆上传与自我同一性的哲学-技术综合分析
记忆上传与自我同一性的哲学-技术综合分析 在2025年的科技前沿,记忆上传技术已取得突破性进展,但其引发的"自我同一性"问题远比技术实现更为复杂。当记忆被上传至云端,所形成的是真实的自我延续,还是仅仅是一个数据的副…...
人工智能工程师学习路线总结(下)
目录 人工智能工程师学习路线总结(下) 十、深度学习框架进阶 (一)TensorFlow分布式训练 (二)PyTorch模型优化 十一、自然语言处理(NLP)进阶 (一)Transf…...
Vue:axios(POST请求)
发送 POST 请求 基本用法 axios.post(/api/login, {username: lcyyyy,password: 123456 }) .then(response > {console.log(请求成功:, response.data); }) .catch(error > {console.error(请求失败:, error); });在 Vue 组件中使用 export default {methods: {async …...
企业级调度器LVS (面试版)
1. 什么是 LVS?有什么作⽤? LVS ( Linux Virtual Server )是⼀个基于 Linux 内核实现的⾼性能、可扩展和可靠的负载均衡。它将多个服务器组成⼀个⾼可⽤、⾼性能和⾼可靠的虚拟服务器集群,通过将客户端的请求转发到不同的后端服务器,实现负载均衡和⾼可⽤性。 2.什么是 …...

从OTA双雄「共舞」,透视旅游持续繁荣背后的结构性跃迁
2025年,中国旅游市场仍在持续复苏中。 文化和旅游部发布的国内出游数据显示,2025年一季度,国内出游人次17.94亿,比上年同期增加3.75亿,同比增长26.4%;国内居民出游总花费1.80万亿元,比上年同期…...

华为OD机试真题——虚拟理财游戏(2025A卷:200分)Java/python/JavaScript/C/C++/GO最佳实现
2025 A卷 200分 题型 本专栏内全部题目均提供Java、python、JavaScript、C、C++、GO六种语言的最佳实现方式; 并且每种语言均涵盖详细的问题分析、解题思路、代码实现、代码详解、3个测试用例以及综合分析; 本文收录于专栏:《2025华为OD真题目录+全流程解析+备考攻略+经验分…...
Vue-01(Vue CLI创建项目以及文件配置说明)
了解 Vue CLI 及其功能 Vue CLI 是搭建、构建和管理 Vue.js 项目的标准工具。它通过提供一致的项目结构、处理复杂的构建配置以及通过插件提供一组丰富的功能来简化开发工作流程。了解 Vue CLI 对于任何 Vue.js 开发人员来说都至关重要,因为它可以显着提高生产力并…...

华为云Flexus+DeepSeek征文 | DeepSeek-V3/R1商用服务开通体验全流程及使用评测
作者简介 我是摘星,一名专注于云计算和AI技术的开发者。本次通过华为云MaaS平台体验DeepSeek系列模型,将实际使用经验分享给大家,希望能帮助开发者快速掌握华为云AI服务的核心能力。 目录 1. 前言 2. 开通DeepSeek-V3/R1商用服务 2.1 准…...
redis列表类型
练习命令使用,具体如下: lpush llen lrange lpoprpush lindex lset rpop linsert LPUSH命令用来向列表左边增加元素,返回值表示增加元素后列表的长度 127.0.0.1:6379> lpush letter A B C (integer) 3 127.0.0.1:6379> type letter …...

人工智能数学基础实验(一):智能推荐系统实战
一、实验目的 本次实验旨在通过构建用户相似度矩阵和实现个性化推荐,帮助我们直观理解推荐系统的核心原理及其背后的数学基础。具体目标如下: 运用 Python 计算用户间的评分相似度,掌握余弦相似度等数学工具在衡量用户偏好中的应用ÿ…...

uni-app学习笔记十二-vue3中组件传值(对象传值)
一.单对象传值 父组件定义对象的值 <template><view><UserInfo :obj"userinfo"></UserInfo></view> </template><script setup>import {ref} from "vue"const userinfo ref({name:"蛛儿",avatar:&…...