当前位置: 首页 > news >正文

【Linux网络与网络编程】13.五种 IO 模型

前言

在前面的学习中,有一个问题一直没有展开来说,即 IO 问题。 IO 到底有多少种方式呢?什么是高效的 IO 呢?

IO 本质上就是 INPUT 和 OUTPUT 。在网络中 INPUT 就是从网卡中获取数据,而 OUTPUT 就是向网卡中发送数据。 IO 可以理解为等+拷贝。当 IO 事件就绪时就可以进行拷贝了,所以所谓的高效的 IO 就是让 IO 大部分时间处于拷贝而减少等待的时间。

那么如何高效的IO呢?这就提出了五种IO模型来提高 IO 效率。

1. 五种 IO 模型概述

阻塞 IO

阻塞 IO 即在内核将数据准备好之前,系统调用会一直等待。所有的套接字默认都是阻塞方式。阻塞 IO 是最常见的 IO 方式。

非阻塞 IO

非阻塞 IO 即在内核还未将数据准备好时,系统调用仍然会直接返回,并且返回 EWOULDBLOCK 错误码。

信号驱动 IO

信号驱动 IO 即当内核将数据准备好的时,会使用 SIGIO 信号通知应用程序进行 IO 操作。

多路转接 IO

虽然从流程图上看起来和阻塞 IO 类似,但实际上最核心在于 IO 多路转接能够同时等待多个文件描述符的就绪状态。

异步 IO

异步 IO 即由内核在数据拷贝完成时,通知应用程序(而信号驱动是告诉应用程序何时可以开始拷贝数据)。

针对上述 IO 方式我们进行分析:

1. 阻塞 IO vs 非阻塞 IO

IO = 等 + 拷贝。它们等的方式不同,但是 IO 效率实际上是相同的。平常所说的非阻塞 IO 的效率高是因为它可以在等的时候做其他的事情。

2. 这五种 IO 模型哪个效率最高

当然是多路转接 IO 了,因为它能接收到数据就绪的概率更大了。

3. 信号驱动 IO 特点是什么?效率如何?

它逆转了获取就绪事件的方式,效率同阻塞 IO 和非阻塞 IO 相同,因为它们只是等的方式不同而已。

4. 同步 IO vs 异步 IO

我们介绍的前四种 IO 方式是同步 IO。同步 IO 和异步 IO 的本质区别就是有没有参与 IO 的过程。

针对上述的五种 IO 模型,我们会具体介绍非阻塞 IO 和多路转接 IO ,其中本篇博客的下一部分介绍非阻塞 IO ,下一篇博客将具体介绍多路转接 IO 。

2. 非阻塞 IO

其实之前学习过的很多函数都可以通过设置标记位的方式来实现非阻塞,但是Linux下一切皆文件,故而就产生了更为通用的设置方式,即对文件描述符进行操作。

#include <fcntl.h>
int fcntl(int fd, int op, ... /* arg */ );// 参数: 
//     fd:需要被操作的文件描述符
//     op:要进行的设置操作
//        F_DUPFD: 复制一个现有的描述符
//        F_GETFD 或 F_SETFD:获得/设置文件描述符标记
//        F_GETFL 或 F_SETFL:获得/设置文件状态标记
//        F_GETOWN 或 F_SETOWN:获得/设置异步 I/O 所有权
//        F_GETLK 获 F_SETLK 或 F_SETLKW:获得/设置记录锁
// 返回值:
//    成功的话依赖于所请求的内容,失败的话返回 -1

非阻塞如果不输入,数据就不会就绪,并以出错的形式返回。但是 read 不是有读取错误吗,两者如何区分呢?

如果读取错误的话就会被设置错误码 errno ,里面会有更详细的错误信息,但是如果是底层数据没有就绪的话就会触发11号错误 EAGAIN(EWOULDBLOCK)。

补充知识:

read 的阻塞是调用系统调用而进入了浅层睡眠 s 状态,而 s 状态收到信号也可能会被叫醒的!这样的情况错误码就是 EINTR 。

接下来我们写一段demo代码:

#include <iostream>
#include <cstdio>
#include <string>
#include <cerrno>
#include <unistd.h>
#include <fcntl.h>void SetNonBlock(int fd)
{// 获取得到文件描述符int fl = fcntl(fd, F_GETFL);if (fl < 0){perror("fcntl");return;}// 将文件描述符的属性置为非阻塞fcntl(fd, F_SETFL, fl | O_NONBLOCK);
}int main()
{std::string tips = "Please Enter# ";char buffer[1024];SetNonBlock(0);while (true){write(0, tips.c_str(), tips.size());int n = read(0, buffer, sizeof(buffer));if (n > 0){buffer[n] = 0;std::cout << "echo# " << buffer << std::endl;}else if (n == 0){std::cout << "read file end!" << std::endl;break;}else{if (errno == EAGAIN || errno == EWOULDBLOCK){std::cout << "底层数据,没有就绪" << std::endl;sleep(1);continue;}else if (errno == EINTR){std::cout << "被中断,从新来" << std::endl;sleep(1);continue;}else{std::cout << "read error: " << n << ", errno: " << errno << std::endl;}}}
}

相关文章:

【Linux网络与网络编程】13.五种 IO 模型

前言 在前面的学习中&#xff0c;有一个问题一直没有展开来说&#xff0c;即 IO 问题。 IO 到底有多少种方式呢&#xff1f;什么是高效的 IO 呢&#xff1f; IO 本质上就是 INPUT 和 OUTPUT 。在网络中 INPUT 就是从网卡中获取数据&#xff0c;而 OUTPUT 就是向网卡中发送数据…...

Java后端开发day37--源码解析:TreeMap可变参数--集合工具类:Collections

&#xff08;以下内容全部来自上述课程&#xff09; 1. TreeMap 1.1 须知 1.1.1 Entry 节点初始为黑色&#xff1a;提高代码阅读性 1.1.2 TreeMap中的成员变量 comparator&#xff1a;比较规则root&#xff1a;红黑树根节点的地址值size&#xff1a;集合的长度和红黑树…...

海关 瑞数 后缀分析 rs

声明 本文章中所有内容仅供学习交流使用&#xff0c;不用于其他任何目的&#xff0c;抓包内容、敏感网址、数据接口等均已做脱敏处理&#xff0c;严禁用于商业用途和非法用途&#xff0c;否则由此产生的一切后果均与作者无关&#xff01; 逆向过程 部分python代码 cp execj…...

【合新通信】---Mini单路光模块(Mini SFF/USOT)

产品特性 l 高可靠、全金属外壳、抗振动设计 l 紧凑的结构设计, 超小模块尺寸 l 可插拔标准LC单模光纤连接器接口&#xff0c;方便动态和灵活的配置数据连接 l 每通道工作速率可达1.25Gbps&#xff0c;速率可向下兼容 l 单路发射光纤通道&#xff0c;内置1310nm波长光发射…...

Java详解LeetCode 热题 100(02):LeetCode 49. 字母异位词分组(Group Anagrams)详解

文章目录 1. 题目描述2. 理解题目3. 解法一:排序法3.1 思路3.2 Java代码实现3.3 代码详解3.4 复杂度分析3.5 适用场景4. 解法二:计数法4.1 思路4.2 Java代码实现4.3 代码详解4.4 复杂度分析4.5 适用场景5. 解法三:字符串哈希法5.1 思路5.2 Java代码实现5.3 代码详解5.4 复杂…...

【每日随笔】文化属性 ① ( 天机 | 强势文化与弱势文化 | 文化属性的形成与改变 | 强势文化 具备的特点 )

文章目录 一、文化属性1、天机2、文化属性的强势文化与弱势文化强势文化弱势文化 二、文化属性的形成与改变1、文化属性形成2、文化属性改变3、文化知识的阶层 三、强势文化 具备的 特点 一、文化属性 1、天机 如果想要 了解这个世界的 底层架构 , 就需要掌握 洞察事物本质 的能…...

Java + Seleium4.X + TestNG自动化技术

系列文章目录 文章目录 系列文章目录前言一、 Java版Selenium自动化测试框架介绍和原理1.1 什么是Seleium1.2 特点1.3 注意点 二、安装SeleiumChrome环境 创建Maven项目2.1 安装Seleium Chrome环境2.2 Maven环境 三、Selenium4.X UI元素定位实战3.1 ID选择器3.2 Name选择器3.…...

Spark SQL核心概念与编程实战:从DataFrame到DataSet的结构化数据处理

一、Spark-SQL是什么 Spark SQL 是 Spark 用于结构化数据(structured data)处理的 Spark 模块。 二、Hive and SparkSQL SparkSQL 的前身是 Shark&#xff0c;Shark是给熟悉 RDBMS 但又不理解 MapReduce 的技术人员提供的快速上手的工具。 Hive 是早期唯一运行在 Hadoop 上的 S…...

electron-vite 应用打包自定义图标不显示问题

// 修改electron-builder.yml ... win:executableName: xxx //可执行文件名称icon: build/icon.ico //你的图标路径 ...打包后&#xff0c;自定义图标不显示原因: 1 cannot execute causeexit status 2&#xff0c;安装包无法生成 用管理员身份运行&#xff0c;win11右击开始…...

AI中Token的理解与使用总结

AI中Token的理解与使用总结 什么是Token 在AI领域,特别是自然语言处理(NLP)中,Token是指将文本分割成的最小处理单元。Tokenization(分词)是将原始文本分解为Token的过程。 Token的几种形式 单词级Token:以单词为基本单位 示例:“Hello world” → [“Hello”, “world”…...

C++/SDL 进阶游戏开发 —— 双人塔防(代号:村庄保卫战 14)

&#x1f381;个人主页&#xff1a;工藤新一 &#x1f50d;系列专栏&#xff1a;C面向对象&#xff08;类和对象篇&#xff09; &#x1f31f;心中的天空之城&#xff0c;终会照亮我前方的路 &#x1f389;欢迎大家点赞&#x1f44d;评论&#x1f4dd;收藏⭐文章 文章目录 二…...

全栈量子跃迁:当Shor算法破解RSA时,我们如何用晶格密码重构数字世界的信任基岩?

一、量子威胁的降维打击 1. Shor算法的毁灭性力量 # Shor算法量子电路简化示例&#xff08;Qiskit实现&#xff09; from qiskit import QuantumCircuit from qiskit.circuit.library import QFTdef shor_circuit(n: int, a: int) -> QuantumCircuit:qc QuantumCircuit(2…...

python实战项目65:drissionpage采集boss直聘数据

python实战项目65:drissionpage采集boss直聘数据 一、需求简介二、流程分析三、完整代码一、需求简介 boss直聘网站近期改版,改版之后代码需要做相应的升级维护。drissionpage采集网页数据是一种不错的方式,笔者认为比Selenium好用,使用方法大家可以自行查阅资料。boss直聘…...

常用的性能提升手段--提纲

上一篇文章里,介绍了提升性能的一种优化手段:池化。 这篇文章来归纳整理一下其他的常见的提升性能的手段 1. 缓存 (Caching) 缓存可以说是计算机领域的万金油了,它无处不在。 举个最简单的例子,CPU -> L1,L2,L3 Cache -> 内存 。 CPU的处理速度要比内存快几个数量…...

天梯——现代战争

第一次做的时候&#xff0c;直接暴力&#xff0c;显然最后超时。 暴力代码如下&#xff1a; #include<bits/stdc.h> using namespace std; const int N10005; bool mark1[N]{0},mark2[N]{0}; int p[N][N]; int main(){int n,m,k,a,b;cin>>n>>m>>k;fo…...

Codeforces Round 1021 (Div. 2) D. Baggage Claim(建图)

每周五篇博客&#xff1a;&#xff08;4/5&#xff09; https://codeforces.com/contest/2098/problem/D 题意 每个机场都有一个行李索赔区&#xff0c;巴尔贝索沃机场也不例外。在某个时候&#xff0c;Sheremetyevo的一位管理员提出了一个不寻常的想法&#xff1a;将行李索…...

常用第三方库:shared_preferences数据持久化

常用第三方库&#xff1a;shared_preferences数据持久化 前言 shared_preferences是Flutter中最常用的轻量级数据持久化解决方案&#xff0c;它提供了一个简单的key-value存储机制&#xff0c;适合存储用户配置、应用设置等小型数据。本文将从实战角度深入讲解shared_prefere…...

项目驱动 CAN-bus现场总线基础教程》随笔

阅读&#xff1a;《项目驱动 CAN-bus现场总线基础教程》 仲裁段的实现 有感而发 感觉出人意外之处 感觉出人意外之处 最近在阅读入门的CAN相关书籍时&#xff0c;在介绍仲裁段是如何实现各节点之间&#xff0c;通讯仲裁功能的章节中&#xff0c;有如下一段描述&#xff1a; …...

WPF之XAML基础

文章目录 XAML基础&#xff1a;深入理解WPF和UWP应用开发的核心语言1. XAML简介XAML与XML的关系 2. XAML语法基础元素语法属性语法集合语法附加属性 3. XAML命名空间命名空间映射关系 4. XAML标记扩展静态资源引用数据绑定相对资源引用常见标记扩展对比 5. XAML与代码的关系XAM…...

测试基础笔记第十四天

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 一、字符串1.字符串2.字符串切片3.查找find&#xff08;&#xff09;4.去除两端空白字符 strip5.字符串转换大小写 lower、upper5.拆分 split()6.字符串的其他常见方…...

Java详解LeetCode 热题 100(01):LeetCode 1. 两数之和(Two Sum)详解

文章目录 1. 题目描述2. 理解题目3. 解法一&#xff1a;暴力枚举法3.1 思路3.2 Java代码实现3.3 代码详解3.4 复杂度分析3.5 适用场景 4. 解法二&#xff1a;哈希表法4.1 思路4.2 Java代码实现4.3 代码详解4.4 复杂度分析4.5 适用场景 5. 解法三&#xff1a;两遍哈希表法5.1 思…...

机器学习之三:归纳学习

正如人们有各种各样的学习方法一样&#xff0c;机器学习也有多种学习方法。若按学习时所用的方法进行分类&#xff0c;则机器学习可分为机械式学习、指导式学习、示例学习、类比学习、解释学习等。这是温斯顿在1977年提出的一种分类方法。 有关机器学习的基本概念&#xff0c;…...

AI声像融合守护幼儿安全——打骂/异常声音报警系统的智慧防护

幼儿园是孩子们快乐成长的摇篮&#xff0c;但打骂、哭闹或尖叫等异常事件可能打破这份宁静&#xff0c;威胁幼儿的身心安全。打骂/异常声音报警系统&#xff0c;依托尖端的AI声像融合技术&#xff0c;结合语音识别、情绪分析与视频行为检测&#xff0c;为幼儿园筑起一道智能安全…...

2024ICPC网络赛第二场题解

文章目录 F. Tourist(签到)I. Strange Binary(思维)J. Stacking of Goods(思维)A. Gambling on Choosing Regionals(签到)G. Game(数学)L. 502 Bad Gateway(数学)E. Escape(BFS)C. Prefix of Suffixes(kmp结论)K. match(01trie分治多项式乘法组合数) 题目链接 F. Tourist(签到…...

风控策略引擎架构设计全解析:构建智能实时决策系统

摘要 本文深入探讨现代风控策略引擎的核心架构设计,结合金融反欺诈、电商交易风控等典型场景,详细解析实时决策、规则引擎、特征计算等关键技术模块的实现方案。通过分层架构设计、分布式计算优化、策略动态编排等创新方法,展示如何构建支撑每秒万级决策的高可用风控系统。…...

TensorFlow 安装全攻略

选择 TensorFlow 的原因&#xff1a; TensorFlow 是一个端到端平台&#xff0c;它提供多个抽象级别&#xff0c;因此您可以根据自己的需求选择合适的级别。您可以使用高阶 Keras API 构建和训练模型&#xff0c;该 API 让您能够轻松地开始使用 TensorFlow 和机器学习。如果您需…...

Dijkstra 算法代码步骤[leetcode.743网络延迟时间]

有 n 个网络节点&#xff0c;标记为 1 到 n。 给你一个列表 times&#xff0c;表示信号经过 有向 边的传递时间。 times[i] (ui, vi, wi)&#xff0c;其中 ui 是源节点&#xff0c;vi 是目标节点&#xff0c; wi 是一个信号从源节点传递到目标节点的时间。 现在&#xff0c;…...

Ubuntu22.04/24.04 P104-100 安装驱动和 CUDA Toolkit

硬件环境 使用一块技嘉 B85m-DS3H 安装 P104-100, CPU是带集成显卡的i5-4690. 先在BIOS中设置好显示设备优先使用集成显卡(IGX). 然后安装P104-100开机. 登入Ubuntu 后查看硬件信息, 检查P104-100是否已经被检测到 # PCI设备 lspci -v | grep -i nvidia lspci | grep NVIDIA …...

Golang 学习指南

目录 变量与常量数据类型与控制结构常用数据结构函数与错误处理指针与并发Gin 框架与 go mod小结与参考资料 1. 变量与常量 变量&#xff08;var&#xff09; 用于定义可变的值。可以指定类型&#xff0c;也可以自动推断类型。示例&#xff1a;var name string "Golang…...

Ubuntu 磁盘空间占用清理(宝塔)

目录 前言1. 基本知识2. 实战 前言 &#x1f91f; 找工作&#xff0c;来万码优才&#xff1a;&#x1f449; #小程序://万码优才/r6rqmzDaXpYkJZF 爬虫神器&#xff0c;无代码爬取&#xff0c;就来&#xff1a;bright.cn 本身自搭建了一个宝塔&#xff0c;突然一下子多了好些空…...

AntBio: 2025 AACR Meeting - Charting New Oncology Frontiers Together

AntBio cordially invites you to attend the 2025 AACR Annual Meeting and jointly chart a new course in oncology research! The global benchmark for cancer research and therapeutics—the 2025 American Association for Cancer Research (AACR) Annual Meeting—wi…...

数模学习:二,MATLAB的基本语法使用

注释代码&#xff1a; (1)在每行语句后面加上分号&#xff0c;则不显示该行代码的运算结果。 在每行代码前加%&#xff0c;则该行代码会被注释掉 (2) 多行注释&#xff1a; 选中要注释的多行语句&#xff0c;按快捷键Ctrl R (3) 取消注释&#xff1a; 选中要注释的多行语句…...

【Webpack \ Vite】多环境配置

环境变量脚本命令 如何通过不同的环境变量或不同的配置文件进行项目区分&#xff0c;动态加载配置。通常&#xff0c;使用环境变量是最简单且灵活的方法&#xff0c;因为它不需要改变构建命令或创建多个配置文件 环境变量 在根目录下创建 .env.xxx 文件&#xff0c;为不同的环…...

已知漏洞打补丁

. 打补丁 根据MS漏洞编号或者CVE漏洞编号都可以找到对应的HotfixID。 1.根据MS漏洞编号可以使用&#xff1a;https://learn.microsoft.com/zh-cn/security-updates/securitybulletins/securitybulletins 即可找到KB编号。 2.根据CVE漏洞编号可以使用&#xff1a;https://cve…...

WGS84(GPS)、火星坐标系(GCJ02)、百度地图(BD09)坐标系转换Java代码

在做基于百度地图、高德地图等电子地图做为地图服务的二次开发时&#xff0c;通常需要将具有WGS84等坐标的矢量数据&#xff08;如行政区划、地名、河流、道路等GIS地理空间数据&#xff09;添加到地图上面。 然而&#xff0c;在线地图大多使用的是火星坐标系&#xff0c;需要…...

R语言操作n

1.加载安装vegan包 2.查看data(varechem)和data(varespec),探索其维度和结构 3.基于varespec构建物种互作网络&#xff0c;输出gml文件并采用gephi可视化为图片&#xff0c;输出pdf&#xff0c;阈值为r>0.6&#xff0c;p<0.05 4.基于varespec和varechem构建物种-环境互作…...

ChatGPT与DeepSeek在科研论文撰写中的整体科研流程与案例解析

随着人工智能技术的快速发展&#xff0c;大语言模型如ChatGPT和DeepSeek在科研领域展现出强大的潜力&#xff0c;尤其是在论文撰写方面。本文旨在介绍如何利用ChatGPT和DeepSeek提升科研论文撰写的效率与质量&#xff0c;并提供一个具体案例&#xff0c;详细阐述其技术流程及公…...

VScode在 Markdown 编辑器中预览

1. 使用在线 Mermaid 编辑器 步骤&#xff1a; 打开 Mermaid Live Editor。将你 .md 文件中的 Mermaid 代码&#xff08;从 mermaid 到结束的代码块&#xff09;复制粘贴到编辑器的左侧输入框。编辑器会自动在右侧生成可视化的 ER 图。你可以点击右上角的下载按钮&#xff0c;…...

驱动开发硬核特训 · Day 22(下篇): # 深入理解 Power-domain 框架:概念、功能与完整代码剖析

一、Power-domain 框架基础概念 ✏️ 什么是 Power-domain&#xff1f; 在 Linux 内核中&#xff0c;Power-domain&#xff08;电源域&#xff09; 是指一组硬件模块的逻辑集合&#xff0c;这些模块可以被统一控制电源状态&#xff08;上电、断电&#xff09;。 Linux 内核通…...

无人机超声波避障技术要点与难点!

一、超声波避障技术要点 4. 障碍物建模 通过最小二乘法平面拟合&#xff0c;将单点测距数据转化为障碍物表面模型&#xff0c;提高避障准确性。 使用队列&#xff08;wallqueue&#xff09;存储障碍物信息&#xff0c;并进行去重处理&#xff0c;避免重复避障。 5. 避障轨…...

ASCII字符编码标准及字符表

目录 概述 1 标准 ASCII 表&#xff08;0-127&#xff09; 2 大写字母&#xff08;A-Z&#xff09; 3 小写字母&#xff08;a-z&#xff09; 4 说明 概述 ASCII&#xff08;American Standard Code for Information Interchange&#xff0c;美国信息交换标准代码&#xff…...

联想昭阳笔记本 风扇一键静音优化操作指南

【联想昭阳笔记本 一键静音优化操作指南】 第1步&#xff1a;安装官方工具 Lenovo Vantage 打开【开始菜单】→ 搜索【Microsoft Store】&#xff0c;打开。在 Store 里搜索【Lenovo Vantage】&#xff0c;下载安装。安装好后&#xff0c;打开【Lenovo Vantage】。进入【设备…...

go语言八股文(三)

1.java和go的区别 1. 语言设计目标 Java&#xff1a; 通用性&#xff1a;设计为一种通用的、面向对象的编程语言&#xff0c;适用于多种应用场景&#xff0c;如桌面应用、服务器端应用、移动应用等。跨平台性&#xff1a;通过“一次编写&#xff0c;到处运行”&#xff08;Wr…...

Flutter 学习之旅 之 flutter 有时候部分手机【TextField】无法唤起【输入法软键盘】的一些简单整理

Flutter 学习之旅 之 flutter 有时候部分手机【TextField】无法唤起【输入法软键盘】的一些简单整理 目录 Flutter 学习之旅 之 flutter 有时候部分手机【TextField】无法唤起【输入法软键盘】的一些简单整理 一、简单介绍 二、现象描述 三、尝试的解决方案 1、根据应用的…...

【工具】scMultiMap基于单细胞多模态数据实现增强子与靶基因的细胞类型特异性映射

文章目录 介绍代码参考 介绍 在与疾病相关的细胞类型中绘制增强子和靶基因图谱&#xff0c;能够为全基因组关联研究&#xff08;GWAS&#xff09;变异的功能机制提供关键见解。单细胞多模态数据能够测量同一细胞中的基因表达和染色质可及性&#xff0c;从而实现细胞类型特异性…...

rt-linux下的cgroup cpu的死锁bug

一、背景 rt-linux系统有其非常大的实时性的优势&#xff0c;但是与之俱来的是该系统上有一些天然的缺陷。由于rt-linux系统允许进程在内核态执行的逻辑里&#xff0c;在持锁期间&#xff0c;甚至持spinlock锁期间&#xff0c;都能被其他进程抢占。这一特性能带来实时性的好处…...

Java 内存泄漏 详解

Java 内存泄漏是指程序中某些对象不再被使用&#xff0c;但由于某些原因无法被垃圾回收器&#xff08;Garbage Collector, GC&#xff09;回收&#xff0c;导致内存被持续占用&#xff0c;最终可能引发性能问题或 OutOfMemoryError。 本文将从底层原理、源码层面详细解释 Java …...

Rabbit MQ的基础认识

零、介绍 MQ&#xff1a;message queue&#xff08;消息队列&#xff1a;先进先出&#xff09; Rabbit MQ&#xff1a; 一、优势 1.应用解耦 2.异步提速 3.削峰填谷 4.总结 二、劣势...

GIS开发笔记(16)解决基于osg和osgearth三维地图上添加placeNode图标点击不易拾取的问题

一、实现效果 二、实现原理 在图标添加的位置同时添加一个红色圆球,半径为5000~8000米,图标和圆球挂接到同一个group节点,group节点再挂接到根节点,当点击到圆球时,通过遍历父节点就可以找到被点击的图标节点。 三、参考代码 //添加图标代码 #pragma once #include &…...

JDBC 使用流程详解

1. 加载数据库驱动 目的&#xff1a;注册数据库驱动类&#xff0c;使 JDBC 能识别特定数据库&#xff08;如 MySQL、Oracle&#xff09;。 代码示例&#xff1a; // JDBC 4.0 后无需显式加载驱动&#xff08;SPI 自动发现&#xff09;&#xff0c;但部分旧项目仍需手动加载 C…...