基于多反应堆的高并发服务器【C/C++/Reactor】(中)ChannelMap 模块的实现
(三)ChannelMap 模块的实现
这个模块其实就是为Channel来服务的,前面讲了Channel这个结构体里边它封装了文件描述符。假如说我们得到了某一个文件描述符,需要基于这个文件描述符进行它对应的事件处理,那怎么办呢?我们就需要找到文件描述符对应的那个Channel,因为在这个Channel里边有事件对应的回调函数,只有找到Channel之后,我们才能够知道当读事件被触发了,或者说写事件被触发了。咱们调用的函数是什么呢?在C语言里,没有stl容器的,那如何实现一个对应关系呢?最简单的方式就是使用数组。有一种查找效率更高的数据结构就是哈希,其实它就是通过数组来实现的。通过空间换时间,牺牲一部分内存空间换取数据的读取效率。看下图,对于每个数组来说,都有一个唯一的下标,是从零开始的,对于文件描述符来说,最小值也是零,所以我们可以让数组的下标去对应文件描述符,0号下标对应0号文件描述符,1号下标对应1号文件描述符。假设说和客户端建立了一个连接,得到了5号文件描述符,那么前边的这些文件描述符是不是有可能是空的?也就是说下标对应的值是空的,这个有关系吗?没关系啊,因为前边说的咱们实现的这种map,主要的思路是空间换时间,所以要换取效率,必然是要牺牲一部分空间的。使用了这种方式,就直接能够通过下标来取出对应的值,不需要遍历。
主要介绍了ChannelMap的实现思路,包括使用数组和哈希等数据结构,以及如何通过空间换时间来提高查找效率。同时,还介绍了如何定义map对应的那个结构体,以及如何实例化这个数组。
核心观点:
- 使用数组或哈希等数据结构实现ChannelMap,以提高查找效率。
- 通过空间换时间的思想,牺牲一部分空间来换取效率。
- 在map对应的结构体中,主要的数据成员是一个数组,数组的大小需要根据实际情况确定。
- 需要实例化数组,并确定数组中存储的指针类型。
ChannelMap相关函数
(1) channelMapInit
功能:为ChannelMap分配内存
- 分配内存给指针。
- 计算内存大小:size * 指针的字节数(指针为4字节)。
- 将map指针的地址返回给调用者。
(2) ChannelMapClear
功能:清空ChannelMap结构体。
- 判断map是否为空。
- 遍历数组,释放指针指向的内存(如果指针不为空)。
- 释放数组指向的内存。
- 将数组的size置为0。
注意事项:内存释放分为两部分,数组元素指向的内存和数组本身指向的内存。
(3) makeMapRoom 数组扩容函数
功能:判断并扩容ChannelMap中的list。
- 判断当前list的size是否大于newSize。
- 如果需要扩容,调用realloc函数重新分配更大的内存给list。
注意事项:只有当map中的size小于newSize时才需要进行扩容操作。
- Channel.h
#pragma once
#include "Channel.h"
struct ChannelMap {struct Channel** list;int size;// 记录指针指向的数组的元素总个数
};// 初始化
struct ChannelMap* channelMapInit(int size);// 清空map
void ChannelMapClear(struct ChannelMap* map);// 重新分配内存空间
bool makeMapRoom(struct ChannelMap* map,int newSize,int unitSize);
- Channel.c
#include "ChannelMap.h"
#include <stdio.h>
#include <stdlib.h>
struct ChannelMap* channelMapInit(int size) {struct ChannelMap* map = malloc(sizeof(struct ChannelMap));map->size = size;map->list = (struct Channel**)malloc(sizeof(struct Channel*) * size);return map;
}void ChannelMapClear(struct ChannelMap* map) {if(map != NULL) {for(int i=0;i<map->size;++i) {if(map->list[i] != NULL) {free(map->list[i]);}}free(map->list);map->list = NULL;}map->size=0;
}bool makeMapRoom(struct ChannelMap* map,int newSize,int unitSize) {if(map->size < newSize) {int curSize = map->size;// 容量每次扩大原来的一倍while(curSize < newSize) {curSize*=2;}// 扩容 reallocstruct Channel** temp = realloc(map->list,curSize * unitSize);if(temp == NULL) {return false;}map->list = temp;memset(&map->list[map->size],0,(curSize - map->size) * unitSize);map->size = curSize;}return true;
}
第一个精彩片段:channelMapInit函数的实现,详细介绍了如何为ChannelMap分配内存,包括计算内存大小和返回map指针的地址。对于理解ChannelMap如何创建和初始化非常重要,有助于理解后续的函数如何工作。
第二个精彩片段:ChannelMapClear函数的实现,详细介绍了如何清空ChannelMap结构体,包括释放内存和重置size。 这个片段对于理解如何管理和释放内存资源非常重要,有助于避免内存泄漏和其他相关问题。
内容概要:详细介绍了三个函数:channelMapInit、ChannelMapClear和makeMapRoom 对数组扩容函数的实现。这三个函数用于创建、初始化、清空和释放ChannelMap的内存,以及在必要时扩容数组。
核心观点:
- channelMapInit函数主要负责为ChannelMap分配内存,包括为指针成员分配内存,并根据元素个数和指针的字节数计算内存大小。
- ChannelMapClear函数用于清空ChannelMap结构体,包括释放数组元素指向的内存和数组本身指向的内存,并将数组的size置为0。
- 对数组扩容函数需要判断当前数组的size是否小于newSize,如果需要扩容,则调用realloc函数重新分配更大的内存给数组。
相关文章:

基于多反应堆的高并发服务器【C/C++/Reactor】(中)ChannelMap 模块的实现
(三)ChannelMap 模块的实现 这个模块其实就是为Channel来服务的,前面讲了Channel这个结构体里边它封装了文件描述符。假如说我们得到了某一个文件描述符,需要基于这个文件描述符进行它对应的事件处理,那怎么办呢&…...
微信小程序实现一个音乐播放器的功能
微信小程序实现一个音乐播放器的功能 要求代码实现wxml 文件wxss 文件js文件 解析 要求 1.页面包含一个音乐列表,点击列表中的音乐可以播放对应的音乐。 2.播放中的音乐在列表中有标识,并且可以暂停或继续播放。 3.显示当前音乐的播放进度和总时长&#…...

算法基础之表达整数的奇怪方式
表达整数的奇怪方式 中国剩余定理: 求M 所有m之积 然后Mi M / mi x 如下图 满足要求 扩展中国剩余定理 找到x **使得x mod mi ai**成立 对于每两个式子 都可以推出①式 即 用扩展欧几里得算法 可以算出k1,-k2和m2–m1 判无解 : 若**(m2–m1) % d ! 0** 说明该等式无解 …...

WEB 3D技术 three.js 设置图像随窗口大小变化而变化
本文 我们来讲讲我们图层适应窗口变化的效果 可能这样说有点笼统 那么 自适应应该大家更熟悉 就是 当我们窗口发生变化说 做一些界面调整比例 例如 我们这样一个i项目界面 我们打开 F12 明显有一部分被挡住了 那么 我们可以刷新 这样是正常了 但是 我们将F12关掉 给F12的…...

实战案例:缓存不一致问题的解决(redis+本地缓存caffine)
一.问题引入 目前在写项目的时候,在B端查看文章,A端修改文章。为了增加效率,以及防止堆内存溢出,在B端选择本地缓存文章的方案。但是目前出现了A端对文章修改之后,B端读的还是旧数据,出现了缓存不一致的问…...
【开源CDP】市场增长未来的探索,开源CDP带来的技术崛起与变革
数字化趋势之下,数据成了企业竞争的核心资源,不管是公域还是私域,网络俨然成了品牌打响市场的一线战场,然而,在这场数字战役里,许多企业不得不面临一个共同问题:数据零散、分散、平台众多、无法…...

第11章 GUI Page423~424 步骤六 支持文字,使用菜单,对话框输入文字
运行效果: 点击OK,然后再窗口上按住左键,拖动鼠标 关键代码: 新增头文件和成员,新增私有成员_text 成员初始化 为菜单项MenuItemText添加响应函数 新增创建TextItem()的代码...
【Qt】Qt Creator 警告: Unused parameter ‘xxx‘
1. 问题 Qt开发中,有些函数参数没有使用,会报Unused parameter xxx警告,这个警告不影响代码正常运行。 2. 屏蔽这个警告的方法 2.1 方法1 函数中添加 Q_UNUSED(arg); TestClass::TestClass(QObject *parent) {Q_UNUSED(parent); }2.2 方…...

「Vue3面试系列」Vue3.0性能提升主要是通过哪几方面体现的?
文章目录 一、编译阶段diff算法优化静态提升事件监听缓存SSR优化 二、源码体积三、响应式系统参考文献 一、编译阶段 回顾Vue2,我们知道每个组件实例都对应一个 watcher 实例,它会在组件渲染的过程中把用到的数据property记录为依赖,当依赖发…...
网络结构模式
一、C/S结构 服务器 - 客户机,即 Client - Server ( C/S )结构。 C/S 结构通常采取两层结构。服务器负责数据的 管理,客户机负责完成与用户的交互任务。客户机是因特网上访问别人信息的机器,服务器则是提 供信息供人…...
IIC及OLED实验
I2C (Inter-Integrated Circuit): I2C 是一种用于在芯片之间进行短距离数字通信的串行通信协议。它允许多个设备通过两根导线(一根数据线 SDA 和一根时钟线 SCL)进行通信。I2C 常常用于嵌入式系统中连接传感器、存储器、显示屏和其他外设。 数据线和时钟…...
day6 力扣公共前缀--go实现---对字符串的一些思考
今日份知识: curl -x 指定方法名 请求的url -d 请求体body里面的内容 //curl命令 curl -x Get 127.0.0.1:8080/add/user -d jinlicurl如果不指定方法,默认使用get方法,在go里面,get方法到底可以不可以把内容数据写在body里面传…...

27.Java程序设计-基于Springboot的在线考试系统小程序设计与实现
1. 引言 随着数字化教育的发展,在线考试系统成为教育领域的一项重要工具。本论文旨在介绍一个基于Spring Boot框架的在线考试系统小程序的设计与实现。在线考试系统的开发旨在提高考试的效率,简化管理流程,并提供更好的用户体验。 2. 系统设…...

Redis可视化工具Redis Desktop Manager mac功能特色
Redis Desktop Manager mac是一款非常实用的Redis可视化工具。RDM支持SSL / TLS加密,SSH隧道,基于SSH隧道的TLS,为您提供了一个易于使用的GUI,可以访问您的Redis数据库并执行一些基本操作:将键视为树,CRUD键…...
【C++】揭开运算符重载的神秘面纱
目录 一、引言 优点 二、介绍 1.定义 2.语法 三、示例 1.加法运算符重载 2.一元运算符重载 3.友元函数 4.流插入和流提取 5.自增自减运算符 总结 一、引言 何为运算符重载?运算符重载,是C中的一项强大特性,赋予了程序员在自定义类…...

竞赛保研 基于LSTM的天气预测 - 时间序列预测
0 前言 🔥 优质竞赛项目系列,今天要分享的是 机器学习大数据分析项目 该项目较为新颖,适合作为竞赛课题方向,学长非常推荐! 🧿 更多资料, 项目分享: https://gitee.com/dancheng-senior/po…...

前端常用的开发工具
前端常用的开发工具🔖 文章目录 前端常用的开发工具🔖1. Snipaste--截图工具2. ScreenToGif--gif图片录制3. Typora--Markdown编辑器4. notepad--文本代码编辑器5. uTools--多功能工具6. EV录屏--录屏软件7. Xmind--思维导图8. Apifox -- 接口调试9. Tor…...

鸿蒙开发语言介绍--ArkTS
1.编程语言介绍 ArkTS是HarmonyOS主力应用开发语言。它在TypeScript (简称TS)的基础上,匹配ArkUI框架,扩展了声明式UI、状态管理等相应的能力,让开发者以更简洁、更自然的方式开发跨端应用。 2.TypeScript简介 自行补充TypeScript知识吧。h…...

关于“Python”的核心知识点整理大全36
目录 13.4.4 向下移动外星人群并改变移动方向 game_functions.py alien_invasion.py 13.5 射杀外星人 13.5.1 检测子弹与外星人的碰撞 game_functions.py alien_invasion.py 13.5.2 为测试创建大子弹 13.5.3 生成新的外星人群 game_functions.py alien_invasion.py …...

安装nodejs,配置环境变量并将npm设置淘宝镜像源
安装nodejs并将npm设置淘宝镜像源 1. 下载nodejs 个人不喜欢安装包,所以是下载zip包的方式。这里我下载的node 14解压包版本 下载地址如下:https://nodejs.org/dist/v14.15.1/node-v14.15.1-win-x64.zip 想要其他版本的小伙伴去https://nodejs.org/di…...

Docker 离线安装指南
参考文章 1、确认操作系统类型及内核版本 Docker依赖于Linux内核的一些特性,不同版本的Docker对内核版本有不同要求。例如,Docker 17.06及之后的版本通常需要Linux内核3.10及以上版本,Docker17.09及更高版本对应Linux内核4.9.x及更高版本。…...
【Linux】shell脚本忽略错误继续执行
在 shell 脚本中,可以使用 set -e 命令来设置脚本在遇到错误时退出执行。如果你希望脚本忽略错误并继续执行,可以在脚本开头添加 set e 命令来取消该设置。 举例1 #!/bin/bash# 取消 set -e 的设置 set e# 执行命令,并忽略错误 rm somefile…...

智能在线客服平台:数字化时代企业连接用户的 AI 中枢
随着互联网技术的飞速发展,消费者期望能够随时随地与企业进行交流。在线客服平台作为连接企业与客户的重要桥梁,不仅优化了客户体验,还提升了企业的服务效率和市场竞争力。本文将探讨在线客服平台的重要性、技术进展、实际应用,并…...
Java多线程实现之Callable接口深度解析
Java多线程实现之Callable接口深度解析 一、Callable接口概述1.1 接口定义1.2 与Runnable接口的对比1.3 Future接口与FutureTask类 二、Callable接口的基本使用方法2.1 传统方式实现Callable接口2.2 使用Lambda表达式简化Callable实现2.3 使用FutureTask类执行Callable任务 三、…...

2021-03-15 iview一些问题
1.iview 在使用tree组件时,发现没有set类的方法,只有get,那么要改变tree值,只能遍历treeData,递归修改treeData的checked,发现无法更改,原因在于check模式下,子元素的勾选状态跟父节…...
在Ubuntu中设置开机自动运行(sudo)指令的指南
在Ubuntu系统中,有时需要在系统启动时自动执行某些命令,特别是需要 sudo权限的指令。为了实现这一功能,可以使用多种方法,包括编写Systemd服务、配置 rc.local文件或使用 cron任务计划。本文将详细介绍这些方法,并提供…...
Spring AI 入门:Java 开发者的生成式 AI 实践之路
一、Spring AI 简介 在人工智能技术快速迭代的今天,Spring AI 作为 Spring 生态系统的新生力量,正在成为 Java 开发者拥抱生成式 AI 的最佳选择。该框架通过模块化设计实现了与主流 AI 服务(如 OpenAI、Anthropic)的无缝对接&…...

【论文阅读28】-CNN-BiLSTM-Attention-(2024)
本文把滑坡位移序列拆开、筛优质因子,再用 CNN-BiLSTM-Attention 来动态预测每个子序列,最后重构出总位移,预测效果超越传统模型。 文章目录 1 引言2 方法2.1 位移时间序列加性模型2.2 变分模态分解 (VMD) 具体步骤2.3.1 样本熵(S…...
鸿蒙DevEco Studio HarmonyOS 5跑酷小游戏实现指南
1. 项目概述 本跑酷小游戏基于鸿蒙HarmonyOS 5开发,使用DevEco Studio作为开发工具,采用Java语言实现,包含角色控制、障碍物生成和分数计算系统。 2. 项目结构 /src/main/java/com/example/runner/├── MainAbilitySlice.java // 主界…...
ip子接口配置及删除
配置永久生效的子接口,2个IP 都可以登录你这一台服务器。重启不失效。 永久的 [应用] vi /etc/sysconfig/network-scripts/ifcfg-eth0修改文件内内容 TYPE"Ethernet" BOOTPROTO"none" NAME"eth0" DEVICE"eth0" ONBOOT&q…...