- 博客(92)
- 资源 (9)
- 收藏
- 关注
原创 【笔记】用一个更生活化的比喻理解 epoll 反应堆模型和它高效的原因
从 Reactor (服务经理团队):宴会厅里有好几个服务经理(多个线程),每个经理都使用上面提到的“高效经理”(epoll)工作模式,负责照顾一大片区域的客人(管理多个连接的IO事件)。每来一位客人,他就安排好座位(创建连接),然后通过对讲机,把这位客人交给宴会厅内部的服务经理(从 Reactor)。· 极度高效:经理的精力完全用在处理“真正发生”的事情上,避免了无谓的奔波。想象一下,你是一家非常繁忙的餐厅的经理,你的工作就是协调处理顾客的各类需求。第二种方式:高效经理 (Epoll 模型)
2025-10-15 10:28:15
455
原创 【笔记】基于epoll的主从Reactor模式实现,并深入分析epoll的性能优势
这种性能差异使得 epoll 成为现代高性能网络服务器的首选 I/O 多路复用机制,特别是在需要处理大量并发连接的场景中。基于 epoll 的主从 Reactor 模式实现,并深入分析 epoll 的性能优势。· poll:随着连接数增加,CPU 使用率线性增长,性能急剧下降。· 使用 epoll 监控多个客户端连接,实现真正的并发处理。· 接受连接后,将新连接分发给从 Reactor 进行处理。· 使用 epoll 监控监听套接字,处理新连接到达事件。· 运行在独立的线程中,专门负责监听和接受新连接。
2025-10-14 16:38:59
800
原创 【笔记】epoll反应堆模型与直接使用epoll的区别
总厨自己不下厨,只负责协调。总结一下:epoll反应堆模型是在直接epoll基础上的一种架构升级,它通过回调机制实现了事件分发与事件处理的分离,使得程序结构更清晰、更易于维护和扩展,是构建高性能、高并发网络服务的更优选择。在直接epoll模型中,如果某个连接的数据处理非常耗时(比如需要复杂的计算或查询数据库),那么在这个处理完成之前,整个线程都会被阻塞,无法处理其他已经就绪的连接,从而严重影响服务器的响应能力。简单来说,直接epoll模型是“自己动手”的模式,而epoll反应堆模型是“调度派活”的模式。
2025-10-14 10:01:47
449
原创 【笔记】用动车组的例子理解线程和进程的区别
例如,一个文字处理软件可能用一个线程接收输入,另一个线程检查拼写,还有一个线程自动保存,它们共享文档数据,协作提升效率。例如,Web浏览器通常为每个标签页或插件使用独立的进程〔3〕,这样某个页面崩溃不会导致整个浏览器关闭。· 信号量:好比动车组的餐车,会限制同时进入的人数,人满时需在门口排队,出来一个才能进去一个〔2〕〔7〕。· 互斥锁:就像动车组上的洗手间,一次只允许一个人使用,门锁上时其他人必须等待〔2〕〔7〕。· 同步机制 (互斥锁与信号量):当多个线程(车厢)需要安全地共享资源时,需要同步机制。
2025-10-13 16:21:42
480
原创 【笔记】 fork()是什么?
避免僵尸进程:子进程结束时,如果父进程没有“等待”(使用 wait() 或 waitpid() 系统调用)来回收其资源,子进程就会变成“僵尸进程”,占用系统资源。这样,修改操作就在各自的副本上进行,不会影响另一个进程〔6〕〔7〕。使用时需要注意管理,例如父进程在 fork() 后可能需要关闭不再需要的描述符,子进程也应同理〔4〕。CoW 机制避免了不必要的内存拷贝,极大地提高了 fork() 的效率,特别是在创建进程后立即执行新程序的场景下(常与 exec() 函数配合使用)〔6〕。
2025-10-13 15:27:24
543
原创 【笔记】为每个网络连接创建一个独立的进程来处理,是解决C10K问题的一种经典并发模型
解决方案:父进程需要捕获 SIGCHLD 信号(当子进程终止时,内核会向父进程发送此信号),并在信号处理函数中异步地回收子进程资源〔1〕〔2〕〔7〕。当子进程(服务员)结束工作退出后,如果父进程(接待员)不进行“事后登记”(调用 waitpid 回收资源),子进程就会变成“僵尸进程”,占用系统资源。· 什么是僵尸进程:当子进程先于父进程结束,但父进程没有调用 wait() 或 waitpid() 来回收其退出状态,这个子进程就会变成“僵尸进程”〔7〕〔8〕。这部分是标准操作〔1〕〔2〕。
2025-10-13 15:19:55
540
原创 【笔记】C10M 问题的挑战与可能性
虽然通过极端优化(如内核旁路)在特定场景下可以实现,但它目前仍是一项高成本、高复杂度、适用于特定领域(如高频交易、电信核心网、顶级负载均衡器)的前沿技术,而非通用解决方案。对于绝大多数应用场景,通过优化架构(如使用微服务、集群)来分散压力,比追求单机的 C10M 更具可行性和性价比。单机处理千万级并发(C10M)在理论和技术路径上是可行的,并且已经有一些前沿的实践探索。然而,这需要突破传统操作系统内核的网络处理瓶颈,挑战巨大。实现 C10M 的关键在于绕过或重构传统的内核网络协议栈。
2025-10-13 15:06:26
359
原创 【笔记】著名的 Netty 网络编程库,用的是哪一种 C10K 解决方法
著名的 Netty 网络编程库采用的正是 I/O 多路复用 技术来解决 C10K 级别的高并发问题,具体来说是其在 Java 领域的实现——NIO (New I/O) 模型。· 高效线程模型:Netty 通过精心设计的线程模型(如主从 Reactor 多线程模型),用少量的线程即可处理海量的连接和请求,极大地减少了线程上下文切换的开销。因此,Netty 的成功实践,正是 I/O 多路复用技术解决 C10K 问题的一个非常典型和优秀的案例。Netty 与 C10K 的解决方案。
2025-10-13 15:05:55
326
原创 【笔记】网络编程中的C10K问题
简单来说,C10K问题是服务器性能演进中的一个关键挑战,而通过I/O多路复用(特别是epoll/kqueue)技术,我们成功地克服了它,为今天的高并发互联网服务奠定了基础。· 效率低下:内核需要花费大量时间在成千上万个线程间切换,而真正用于处理网络I/O的时间占比很小,导致CPU利用率低下,服务响应缓慢甚至崩溃。· 提出了更高的目标:在解决C10K之后,业界又继续挑战C100K(十万级)、C10M(百万级)甚至更高并发量的性能优化。如果你想了解基于事件驱动的服务器具体代码结构,我们可以继续探讨。
2025-10-13 14:38:57
412
原创 【笔记】epool在游戏服务器开发中实际应用场景
epoll 负责监听所有已连接玩家的 Socket,当某个玩家发出动作指令或聊天信息时,epoll 会立刻通知工作线程,服务器再将该事件(如玩家的新位置)广播给周围的其他玩家,实现低延迟的实时同步。游戏服务器有大量的定时任务,如活动开放、怪物刷新、副本倒计时等。当服务器需要向全服或特定区域的所有玩家推送公告、活动开始通知或系统消息时,epoll 的边缘触发模式结合非阻塞 IO 可以高效地将数据写入大量客户端 Socket,避免在某个输出缓冲区已满的玩家连接上阻塞,从而快速完成大规模广播。
2025-10-13 11:07:42
447
原创 【笔记】聊聊更强大的 epoll
Epoll 通过 epollctl 提前将监控信息注册到内核维护的一个事件表中(通常使用红黑树实现),之后调用 epollwait 时,只需拷贝少量就绪的事件信息,大大减少了开销〔4〕〔7〕〔8〕。它不再像 select/poll 那样每次都要你提供一份完整的待检查名单(fdset 或 pollfd 数组),而是让你先创建一个“任务看板”(epoll 实例),然后通过“任务便签”(epollctl)将需要监视的连接和事件注册到这个看板上。· events:一个由调用者分配的数组,用于输出就绪的事件。
2025-10-11 17:33:11
467
原创 【笔记】用书店的例子解释阻塞IO VS 非阻塞IO
小结:非阻塞IO解决了线程阻塞的问题,允许单线程处理多路IO,但需要通过轮询来检查状态,在连接数多时CPU开销很大。用一个书店购书的场景,可以很好地理解阻塞IO和非阻塞IO的区别,以及它们如何影响服务效率。小结:IO多路复用结合了非阻塞IO的能力和事件通知机制,是现代高性能网络服务器的基石。小结:阻塞IO模型简单直观,但无法同时处理多个请求,资源利用率低,不适合高并发场景。想象一下,你是一家书店里唯一的服务员,你的工作是接待顾客,帮助他们找到并购买书籍。在这种模式下,你是一个非常“专注”的服务员。
2025-10-11 14:39:34
373
原创 【笔记】poll,实现I/O多路复用的一种机制,是 select 的改进版
简单来说,poll 是 select 的增强版,它通过使用一个可扩展的结构体数组,突破了连接数量的限制,使得程序能够更高效地管理更多的网络连接。虽然 poll 解决了 select 的连接数限制问题,但它仍然存在一个性能瓶颈:每次调用 poll,不管连接是否活跃,内核都需要线性扫描整个 pollfd 列表。如果说 select 管家用的是固定大小的纸质名单来记录需要照看的连接,那么 poll 管家则用上了一张可动态扩展的电子清单。// 请求监视的事件(你关心它发生什么,如可读)
2025-10-11 14:38:48
346
原创 【笔记】网络编程中的select
摘要 select是网络编程中的高效I/O多路复用机制,它允许单个进程/线程同时监控多个网络连接。通过三个关键步骤实现:1)准备文件描述符集合;2)调用select函数监控;3)处理就绪连接。虽然select简化了多连接管理,但存在连接数限制(通常1024)、性能开销大等局限性。现代高并发场景中,常被epoll、kqueue等更高效的机制替代。select的核心价值在于实现单线程高效处理多路I/O,是理解网络编程中多路复用的基础概念。
2025-10-11 14:37:48
453
原创 【笔记】kill -9的用法
正确流程:遵循“先礼后兵”的原则:首选 kill PID(即 SIGTERM),无效或超时后再使用 kill -9 PID〔1〕〔5〕。· 谨慎操作:在执行 kill -9 前,务必确认 PID 是否正确,误杀系统关键进程可能导致服务异常甚至系统崩溃〔2〕〔3〕。· 权限限制:普通用户只能终止自己启动的进程,而 root 用户几乎可以终止任何进程(除极少数内核进程外)〔4〕〔6〕。· 特殊进程:对于状态为 Z(僵尸进程)的进程,kill -9 是无效的,需要重启其父进程来清除〔5〕。
2025-10-11 14:37:02
828
原创 【游戏测试工程师】初识游戏测试—你了解它吗?
在很多外行甚至行内非测试岗位人的眼里,游戏测试是很没有技术含量的活儿,门槛低。早期的一些游戏测试确实是这样做的,但如今这样做已经不可能保证游戏的品质,因为如今需要的是具备专业知识和技能的测试人员、高效率的测试方法和行之有效的管理流程,才能保证游戏在开发过程中的质量。不可否认,游戏测试的确需要我们玩游戏,就跟软件测试中你需要对产品了如指掌一样,但不只是玩游戏,还要对各类游戏上手程度以及了解程度都要超于普通的游戏玩家,有时还要扮演一下程序、策划、客服、运营的角色,当然能扮演多少取决于你的能力。...
2022-07-20 17:54:01
884
原创 Solar2D&Corona(一) - Hello World
让我们现在就开始快速的了解一下Corona SDK。下载教程文件HelloWorldTutorial.zipHello World学习CoronaSDK唯一最好的方法就是动手编写一个应用程序。我们用来编写程序的语言叫做Lua。根据传统,我们急需编写一些简单Lua代码,来打印“Hello World”。让我们开始吧!你需要一个文本编辑器来编写你的应用程序。然后,你把文件保存在某个文件夹下,一边Corona模拟器运行它,并显示你要的结果。在文本编辑器中,输入以下内容:print( “Hello W
2022-01-15 17:40:36
3200
原创 软件测试基础测验(一)
1单选(2分)下列关于Grace Hopper的说法不正确的是(A)A.Grace Hopper从未设计过计算机BugB.Grace Hopper实现了世界上第一种商用编程语言COBOLC.Grace Hopper发现了计算机程序中的第一个BugD.Grace Hopper是“IT界十大最有远见人才”中的唯一女性2单选(2分)下列关于Fault、Error和Failure的说法不正确的是(D)A.Error是指软件运行到某个Fault时所产生的错误的中间状态B.Fa
2021-09-27 17:13:03
3235
原创 python杨辉三角形
描述输出10行的杨辉三角形杨辉三角,是二项式系数在三角形中的一种几何排列。每行端点与结尾的数为1,其余每个数字等于上一行的左右两个数字之和。可用此性质写出整个杨辉三角。即第n+1行的第i个数等于第n行的第i-1个数和第i个数之和。即 C(n+1,i)=C(n,i)+C(n,i-1)。
2021-09-24 11:58:41
978
原创 python生成随机密码请编写程序,生成随机密码。具体要求如下:
请编写程序,生成随机密码。具体要求如下:(1)使用 random 库,采用 0x1010 作为随机数种子。
2021-09-24 11:25:10
6289
原创 python列表排序
列表排序描述用户输入一串字符,将其每个字符转化为列表的元素,并对其中的数据按升序排序。 输入格式一串字符,如
2021-09-24 11:06:16
1994
原创 Python列表插入 描述 输入一个字符串 s 和一个非负整数 i, 列表 ls = [‘2‘, ‘3‘, ‘0‘, ‘1‘, ‘5‘],在指定的位置 i 和 列表末尾分别插入用户输入的字符串 s。
列表插入描述输入一个字符串 s 和一个非负整数 i, 列表 ls = [‘2’, ‘3’, ‘0’, ‘1’, ‘5’],在指定的位置 i 和 列表末尾分别插入用户输入的字符串 s。当 i >=5 时,相当于在列表末尾插入两次字符串 s 。输入格式第一行输入一个字符串
2021-09-24 10:51:37
12773
原创 Springboot健康项目-09-创建LoginController
1、新建logincontroller.javapackage com.zsm.sportplay.controller;import com.zsm.sportplay.bean.User;import org.springframework.web.bind.annotation.RequestBody;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bi
2021-08-27 14:55:56
595
原创 Springboot健康项目-08-user实体的创建
package com.zsm.sportplay.bean;import lombok.NoArgsConstructor;/* 用户实体 */@NoArgsConstructorpublic class User { public int id; public String username; //用户名 public String password; //密码 public String email; //邮箱 public St..
2021-08-27 14:44:18
252
原创 Springboot健康项目-07-完成登录和重置事件
1、在main.js导入axios// 导入axiosimport axios from 'axios'// 挂载axios 到Vue的原型prototype的$httpVue.prototype.$http = axios// 设置请求的根路径axios.defaults.baseURL = "http://localhost:9000/"2、设置密码为不可见3、给按钮button添加click方法4、测试结果5、测试弹出login(){ thi
2021-08-27 14:23:35
329
1
原创 Springboot健康项目-06-login校验规则
Form 组件提供了表单验证的功能,只需要通过 rules 属性传入约定的验证规则,并将 Form-Item 的 prop 属性设置为需校验的字段名即可。
2021-08-27 10:26:49
198
原创 Springboot健康项目-05-login加入样式
Login.vue中加入style样式<style >.login_container { background-color: #fff; height: 100%; }.login_box{ width: 450px; height: 300px; background-color: #fff; border-radius: 3px; position: absolute; left: 50%; top: 50%; trans
2021-08-27 10:03:28
174
原创 Springboot健康项目-04-iconfont引入
1、添加输入框icon prefix-icon="el-icon-search"效果:2、到阿里矢量图下载icon下载后放置在assets3、在main.js引入iconfontimport './assets/font/iconfont.css' //引入iconfont4.写入代码5、效果
2021-08-26 15:16:34
281
原创 Springboot健康项目-03-login组件创建
创建Login.vue<template> <div> Login </div></template><style lang="less" scoped></style><script>export default { }</script>修改App.vue把app根组件换成<router-view>标签,自定义路由,重定向到login,.
2021-08-26 14:48:23
198
原创 Springboot健康项目-02-创建前端项目
1.创建vue项目win+R输入cmd打开dos,运行命令:vue ui,进入:Vue 项目管理器2.创建项目手动创建配置,选择功能:Babel、Router、使用配置然后创建项目。添加插件elementUI添加依赖:axios、less-loader、less 然后运行vue项目...
2021-08-26 09:45:28
197
原创 Springboot健康项目-01-后台搭建
1.新建项目工程2.添加依赖3.加载依赖4.因为mybatis需要一个数据源,所以配置一个application.yml# mysqlspring: datasource: #MySQL配置 driverClassName: com.mysql.cj.jdbc.Driver url: jdbc:mysql://localhost:3306/easyproject?useUnicode=true&characterEncoding=UTF-8&us
2021-08-25 16:05:00
271
1
原创 【Spring】Spring入门(十)静态代理模式
代码步骤:接口package com.zsm.demo01;//租房public interface Rent { public void rent();}真实角色package com.zsm.demo01;//房东public class Host implements Rent{ @Override public void rent() { System.out.println("房东要出租房子"); }}.
2021-08-05 15:41:53
153
原创 【Spring】Spring入门(八)spring注解开发
<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaL.
2021-08-05 10:52:02
144
原创 【Spring】Spring入门(七)注解实现自动装配
要使用注解须知:1、导入约束 context约束2、配置注解的支持<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/sc.
2021-08-05 09:34:47
470
原创 【Spring】Spring入门(六)自动装配Bean
<!--byName : 会自动在容器上下文中查找,和自己对象set方法后面的值对应的beanIDbyType : 会自动在容器上下文中查找,和自己对象属性类型相同的bean-->
2021-08-04 15:35:50
306
2
原创 【Spring】Spring入门(四)DI依赖注入环境
依赖注入典型的企业应用程序不包含单个对象(或 Spring 用语中的 bean)。即使是最简单的应用程序也有一些对象,它们协同工作以呈现最终用户所看到的连贯应用程序。下一节将解释如何从定义多个独立的 bean 定义到完全实现的应用程序,其中对象协作以实现目标。依赖注入依赖注入(DI) 是一个过程,其中对象定义它们的依赖项,即它们使用的其他对象,仅通过构造函数参数、工厂方法的参数或在对象实例构造或返回后在对象实例上设置的属性从工厂方法。然后容器 在创建 bean 时注入这些依赖项。这个过程从根本上来说是
2021-08-04 15:01:10
179
原创 【Spring】Spring入门(三)Spring配置说明
1、alias别名 <alias name="user" alias="alias_user"/>2、Bean的配置3、import
2021-08-04 09:34:59
145
2019UML基础教程
2019-01-25
图片转ico格式图标
2019-01-25
文件时间修改器更新文件时间修改文件属性
2019-07-03
UnityHubSetup.exe
2020-07-28
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人
RSS订阅