【Linux】线程、线程控制、地址空间布局

目录
- 1、Linux线程
- 1.1 线程的优缺点
- 1.2 线程异常和用途
- 1.3 线程等待
- 1.3 线程终止
- 1.4 线程分离
- 1.5 线程ID和地址空间布局
- 1.6 线程栈
1、Linux线程
- 进程是一个执行起来的程序,进程 = 内核数据结构 + 代码和数据。进程是承担分配系统资源的实体。
- 线程是执行流,执行粒度比进程更细,是进程内部的一个执行分支。线程是OS调度的基本单位。
进程是承担分配系统资源的基本实体,线程不参与分配,只需要划分进程的资源就可。新线程和主线程谁先运行,是不确定的。线程创建出来,要对进程的时间片进程瓜分。
也就是说进程执行的任务还要被细分成几份给更小的线程去执行,可以想象到线程除了执行粒度比进程更细之外大致相似,也就是说OS也要像管理进程一样管理线程,如果用像管理进程一样的方法管理线程,那么就太复杂了。
Linux执行流,统一称为轻量级进程(LWP),Linux中没有真正意义上的线程,Linux线程概念使用LWP模拟实现。
//新线程
void *run(void *args)
{while (true){cout << "new thread, pid : " << getpid() << endl;sleep(1);}return nullptr;
}int main()
{cout << "I am a process, pid : " << getpid() << endl;pthread_t tid;pthread_create(&tid, nullptr, run, (void*)"thread_1");//主线程while (true){cout << "main thread, pid : " << getpid() << endl;sleep(1);}return 0;
}
虚拟内存可以将不连续的物理内存通过映射转化为连续的。当我们讨论虚拟地址到物理地址转换的时候,页表的映射关系已经在加载的时候关联好了。虚拟地址到物理地址转换的过程,是硬件(MMU)自动完成的。
:》如何理解进程划分资源给线程,如何做到?需要刻意做吗?
线程执行不同的入口函数,就拥有了这个函数的地址,资源自然而然就被划分好了。
虚拟地址和物理地址如何转换:
页表可以看作一个简单的数组,前20位用来映射物理地址,后12位作为标记位。
:》所以我们怎么知道当前内存是否被使用呢?
通过页表的映射我们可以得到页框的起始地址,在用起始地址除以4KB,就得到了管理物理内存数组的下标,通过下标也就找到了管理这个内存的信息。
缺页中断:当程序代码量大时只加载部分代码,执行完这部分代码后再往后执行就会在页表的标记位(是否命中)中发现错误,CPU出错触发软中断,发送信号,OS对这个信号的处理就是加载剩余代码,这个过程就是缺页中断。
1.1 线程的优缺点
| 线程优点:
-
创建一个线程的代价比创建一个进程的代价小的多。
-
与进程之间的切换相比,线程之间的切换需要OS做的工作要少很多。
- 最主要的区别是线程的切换虚拟内存空间依然是不变的,而进程切换会改变,这两种切换都是操作系统内核完成的,最显著的消耗是需要将寄存器中的内容切换。
- 另一个显著的消耗就是上下文的切换会扰乱处理器的缓存机制,当改变虚拟内存空间的时候,处理的页表缓冲TLB(快表)(缓存高频的虚拟到物理的映射)和cache(缓存代码和数据块)也会被全部刷新。
-
线程占用的资源比进程少。
-
能充分利用多处理器的可并行数量。
-
在等待慢速IO操作结束的同时,程序可执行其他的计算任务。
-
将计算分解到多个线程中实现,还可以同事等待不同的IO操作。
| 线程缺点:
- 如果线程数量过多会有调度的性能损失。
- 健壮性降低,线程之间是缺乏保护的。
- 缺乏访问控制,在一个线程中调用某些OS函数会对整个进程造成影响。
1.2 线程异常和用途
-
单个线程如果出现除零,野指针问题导致线程崩溃,进程也会随着崩溃。
-
线程是进程的执行分支,线程出异常,就类似进程出异常,进而触发信号机制,终止进程,进程终止,该进程内的所有线程也就随即退出。
-
合理的使用多线程,能提高CPU密集型程序的执行效率。
-
合理的使用多线程,能提高IO密集型程序的用户体验。
1.3 线程等待
| 为什么需要线程等待?
- 已经退出的线程,其空间没有被释放,仍然在进程的地址空间内。
- 创建新的线程不会复用刚才退出线程的地址空间。
调用该函数的线程将挂起等待,直到id为thread的线程终止。thread线程以不同的方法终止,通过pthread_join
得到的终止状态是不同的:
- 如果thread线程通过
return
返回,retval
所指向的单元里存放的是thread线程函数的返回值。 - 如果thread线程被别的线程调用
pthread_cancel
异常终止,retval
所指向的单元里存放的是常数PTHREAD_CANCELED
。 - 如果thread线程是自己调用
pthread_exit
终止的,retval
所指向的单元存放的是传给pthread_exit
的参数。 - 如果对thread线程的终止状态不感兴趣,可以传NULL给
retval
参数。
1.3 线程终止
如果需要只终止某个线程而不是终止整个进程,有三种方法:
- 线程调用
return
退出。 - 线程调用
pthread_exit
退出。 - 线程调用
pthread_cancel
取消线程。
任何地方调用exit,表示进程退出。
取消线程,一定是目标线程已经启动了,join
得到的返回值是-1。
需要注意,pthread_exit
或者return
返回的指针所指向的内存单元必须是全局的或者是用malloc
分配的,不能在线程函数的栈上分配,因为当其它线程得到这个返回指针时线程函数已经退出了。
1.4 线程分离
- 默认情况下,新创建的线程是
joinable
的,线程退出后,需要对其进行pthread_join
操作,否则无法释放资源,从而造成系统泄漏。 - 如果不关心线程的返回值,
join
是一种负担,这个时候,我们可以告诉系统,当线程退出时,自动释放线程资源。
主线程可以不等待新线程,将目标线程设置为分离状态。线程可以被分离,也可以自己分离。
| 线程被等待的状态:
joined
:线程需要被join(默认)detach
:线程分离(主线程不需要等待新线程)
注意:在多执行流情况下,主执行流是最后退出的。
这里执行5秒后
join
失败,进程退出,所以线程分离后就不能join
了。
线程不能直接进行程序替换,因为其他部分代码可能正在被其他线程执行,但是可以在线程内部创建子进程,进行程序替换。
1.5 线程ID和地址空间布局
pthread_create
函数会产生一个线程ID,存放在第一个参数指向的地址中。该线程ID和前面说的线程ID不是一回事。
- 线程属性在线程库中维护,就是TCB,线程ID就是线程库中属性在地址空间中的地址。
- 主线程的栈只有一个,其他线程的栈是在共享区中被动态申请出来的。
线程局部存储只能修饰内置类型。
1.6 线程栈
虽然Linux将线程和进程不加区分的统一到了task_struct
,但是对待其地址空间的stack
还是有些区别的。
- 对于Linux进程或者说主线程,简单理解就是main函数的栈空间,在fork的时候,实际上就是复制了父亲的
stack
空间地址,然后写时拷贝(cow)以及动态增长。如果扩充超出该上限,则栈溢出会报段错误(发送段错误信号给该进程)。进程栈是唯一可以访问未映射页而不一定会发生段错误⸺超出扩充上限才报。 - 对于主线程创建的子线程而言,其
stack
不再是向下生长的,而是事先固定下来的,线程栈一般是调用glibc
的pthread
库接口pthread_create
在共享区创建的。也就是说这种栈一旦用尽就没了,这是和创建进程的fork
不同的地方。 - 对于子线程的
stack
,它其实是在进程的地址空间中map
出来的一块内存区域,原则上是线程私有的,但是同一个进程的所有线程生成的时候,是会浅拷贝生成者的task_struct
的很多字段,如果愿意,其它线程也还是可以访问到。
使用容器管理多线程:
#include "Thread.hpp"
#include <unordered_map>
#include <memory>#define NUM 10
using thread_ptr_t = std::shared_ptr<ThreadModule::Thread>;//创建多线程
int main()
{std::unordered_map<std::string, thread_ptr_t> threads;for (int i = 0; i < NUM; i++){thread_ptr_t t = std::make_shared<ThreadModule::Thread>([](){while (true){std::cout << "hello world" << std::endl;sleep(1);}});threads[t->Name()] = t;}for (auto &thread : threads){thread.second->Start();}for (auto &thread : threads){thread.second->Join();}return 0;
}
本篇文章的分享就到这里了,如果您觉得在本文有所收获,还请留下您的三连支持哦~

相关文章:
【Linux】线程、线程控制、地址空间布局
⭐️个人主页:小羊 ⭐️所属专栏:Linux 很荣幸您能阅读我的文章,诚请评论指点,欢迎欢迎 ~ 目录 1、Linux线程1.1 线程的优缺点1.2 线程异常和用途1.3 线程等待1.3 线程终止1.4 线程分离1.5 线程ID和地址空间布局1.6 线程栈 1、…...
【记录】日常|从零散记录到博客之星Top300的成长之路
文章目录 shandianchengzi 2024 年度盘点概述写作风格简介2024年的创作内容总结 shandianchengzi 2024 年度盘点 概述 2024年及2025年至今我创作了786即84篇文章,加上这篇就是85篇。 很荣幸这次居然能够入选博客之星Top300,这个排名在我之前的所有年份…...
网盘资源查找工具---AI功能
01 软件介绍 这是一款融入了ai技术的网盘搜索神器,可以让你更快,更精准的找到自己需要的文件,不管你是找影视,音乐,还是找软件或者学习资料都可以,欢迎前来使用。 02 功能展示 该软件非常简洁ÿ…...
LWJGL轻量级Java游戏库
LWJGL - Lightweight Java Game Library 基本介绍 LWJGL是一个Java库,它支持跨平台访问流行的本地api,这些api在图形(OpenGL, Vulkan)、音频(OpenAL)和并行计算(OpenCL)应用程序的…...
AI智能日志分析系统
文章目录 1.combinations-intelligent-analysis-starter1.目录结构2.pom.xml3.自动配置1.IntelligentAnalysisAutoConfiguration.java2.spring.factories 2.combinations-intelligent-analysis-starter-demo1.目录结构2.pom.xml3.application.yml4.IntelligentAnalysisApplicat…...
详解三种常用标准化:Batch Norm、Layer Norm和RMSNorm
在深度学习中,标准化技术是提升模型训练速度、稳定性和性能的重要手段。本文将详细介绍三种常用的标准化方法:Batch Normalization(批量标准化)、Layer Normalization(层标准化)和 RMS Normalization&#…...
数据压缩算法-差分编码(Delta Encoding)
Delta Encoding(差分编码)是一种数据压缩技术,其核心思想是存储数据之间的差异(delta),而不是原始数据本身。这种方法特别适用于数据序列中相邻元素之间变化较小的情况,可以显著减少存储空间或传…...
Nginx中部署多个前端项目
1,准备前端项目 tlias系统的前端资源 外卖项目的前端资源 2,nginx里面的html文件夹中新建,tlias和sky两个文件夹。 切记这是在nginx/html下创建的 mkdir sky mkdir tlias 把tlias和sky的资源都放到对应的文件夹中 3,编辑配置ngi…...
Level DB --- TableBuilder
TableBuilder是Level DB里面重要的类和模块,它描述了数据如何序列化到文件中,以及数据里面的格式逻辑。它里面包含了之前介绍的多个模块和类。 data block、filter block和index block block格式,之前已经介绍过Level DB --- BlockBuilder-…...
JVM堆空间
一、堆空间的核心概述 一个JVM实例只存在一个堆内存,堆也是Java内存管理的核心区域。Java堆区在JVM启动的时候即被创建,其空间大小也就确定了。是JVM管理的最大一块内存空间。 堆内存的大小是可以调节的。堆可以处于物理上不连续的内存空间中ÿ…...
【Numpy核心编程攻略:Python数据处理、分析详解与科学计算】1.13 降维打击:扁平化操作的六种武器
1.13 降维打击:扁平化操作的六种武器 目录 #mermaid-svg-bbLxDryjxBbXe3tu {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-bbLxDryjxBbXe3tu .error-icon{fill:#552222;}#mermaid-svg-bbLxDryjxBbXe3tu…...
Doris Schema Change 常见问题分析
1. 什么是 Schema Change Schema Change 是在数据库中修改表结构的一种操作,例如添加列、删除列、更改列类型等。 ⚠️Schema Change 限制⚠️ 一张表在同一时间只能有一个 Schema Change 作业在运行。分区列和分桶列不能修改。如果聚合表中有 REPLACE 方式聚合的…...
数据结构之堆排序
文章目录 堆排序版本一图文理解 版本二向下调整建堆向上调整建堆 排升/降序升序 堆排序 版本一 基于已有数组建堆取堆顶元素并删除堆顶元素重新建大根堆,完成排序版本。 图文理解 版本二 前提:必须提供有现成的数据结构堆 数组建堆,首尾…...
实现桌面动态壁纸(三)—— 视频播放的策略
关于动态壁纸这边,其实已经不需要再谈什么东西了,现有的各种文章都在介绍相关的技术。可以说现如今要去制作一个桌面动态壁纸应该不是什么难事。我考虑了很久,决定还是开一篇单独谈谈。可能我说的也不全部正确,您有什么建议随时可…...
C语言程序设计十大排序—希尔排序
文章目录 1.概念✅2.希尔排序🎈3.代码实现✅3.1 直接写✨3.2 函数✨ 4.总结✅ 1.概念✅ 排序是数据处理的基本操作之一,每次算法竞赛都很多题目用到排序。排序算法是计算机科学中基础且常用的算法,排序后的数据更易于处理和查找。在计算机发展…...
2023年版本IDEA复制项目并修改端口号和运行内存
2023年版本IDEA复制项目并修改端口号和运行内存 1 在idea中打开server面板,在server面板中选择需要复制的项目右键,点击弹出来的”复制配置…(Edit Configuration…)“。如果idea上没有server面板或者有server面板但没有springbo…...
Ubuntu 安装 QGIS LTR 3.34
QGIS官方提供了安装指南:https://qgis.org/resources/installation-guide/#linux。大多数linux发行版将QGIS拆分为几个包:qgis、qgis-python、qgis-grass、qgis-plugin-grass、qgis-server,有的包最初安装时被跳过,可以在需要使用…...
win32汇编环境,对话框程序中使用进度条控件
;运行效果 ;win32汇编环境,对话框程序中使用进度条控件 ;进度条控件主要涉及的是长度单位,每步步长,推进的时间。 ;比如你的长度是1000,步长是100,每秒走1次,则10秒走完全程 ;比如你的长度是1000,步长是10,每秒走1次,则100秒走完全程,但每格格子的长度与上面一样 ;以下…...
从ChatGPT热潮看智算崛起
2025年1月7日,科智咨询发布《2025年IDC产业七大发展趋势》,其中提到“ChatGPT开启生成式AI热潮,智能算力需求暴涨,算力供给结构发生转变”。 【图片来源于网络,侵删】 为何会以ChatGPT发布为节点呢?咱们一起…...
APISIX-API服务网关
一、简介 apisix是一款云原生微服务API网关,可以为API提供终极性能、安全性、开源和可扩展的平台。apisix基于Nginx和etcd实现,与传统API网关相比,apisix具有动态路由和插件热加载,特别适合微服务系统下的API管理。 Apisix 的诞生…...
NR_shell运行流程简析
nr_shell 是一套开源 shell 框架,基于框架可创建终端交互功能。 为了记录终端输入指令,以及进行解析处理,nr_shell 提供了一套 cmd 结构体,具体如下:typedef struct static_cmd_function_struct {char cmd[NR_SHELL_CM…...
leetcode_链表 876.链表的中间节点
876.链表的中间节点 给你单链表的头结点 head ,请你找出并返回链表的中间结点。如果有两个中间结点,则返回第二个中间结点。思路:快慢指针,创建两个指针fast和slow,fast指针每次移动两步,slow指针每次移动…...
idea实用设置
一.View 1.配置工具包方便按 二.File->Settings 点开设置然后进行后面的配置 1.这个看个人习惯 2.更新 3.更改菜单字体大小 4.鼠标控制字体大小 5.文件默认字体大小 6. 代码的智能提示功能 7.自动导包 8.编码 9.取消双击shift搜索...
ui-automator定位官网文档下载及使用
一、ui-automator定位官网文档简介及下载 AndroidUiAutomator:移动端特有的定位方式,uiautomator是java实现的,定位类型必须写成java类型 官方地址:https://developer.android.com/training/testing/ui-automator.html#ui-autom…...
Java数据结构方面的面试试题以及答案解析
Java数据结构是在计算机中存储和组织数据的方式,用于高效地处理和管理数据。 以下是一些常见的Java数据结构: 数组(Array):一种线性数据结构,允许通过索引快速访问元素。它存储固定大小的相同类型的元素集…...
微信小程序-点餐(美食屋)02开发实践
目录 概要 整体架构流程 (一)用户注册与登录 (二)菜品浏览与点餐 (三)订单管理 (四)后台管理 部分代码展示 1.index.wxml 2.list.wxml 3.checkout.wxml 4.detail.wxml 小结优点 概要…...
Redis实战(黑马点评)——关于缓存(缓存更新策略、缓存穿透、缓存雪崩、缓存击穿、Redis工具)
redis实现查询缓存的业务逻辑 service层实现 Overridepublic Result queryById(Long id) {String key CACHE_SHOP_KEY id;// 现查询redis内有没有数据String shopJson (String) redisTemplate.opsForValue().get(key);if(StrUtil.isNotBlank(shopJson)){ // 如果redis的数…...
DroneXtract:一款针对无人机的网络安全数字取证工具
关于DroneXtract DroneXtract是一款使用 Golang 开发的适用于DJI无人机的综合数字取证套件,该工具可用于分析无人机传感器值和遥测数据、可视化无人机飞行地图、审计威胁活动以及提取多种文件格式中的相关数据。 功能介绍 DroneXtract 具有四个用于无人机取证和审…...
uniapp使用uni.navigateBack返回页面时携带参数到上个页面
我们平时开发中也经常遇到这种场景,跳转一个页面会进行一些操作,操作完成后再返回上个页面同时要携带着一些参数 其实也很简单,也来记录一下吧 假设从A页面 跳转到 B页面 A页面 直接上完整代码了哈,很简单: <t…...
2025美赛MCM数学建模A题:《石头台阶的“记忆”:如何用数学揭开历史的足迹》(全网最全思路+模型)
✨个人主页欢迎您的访问 ✨期待您的三连 ✨ 《石头台阶的“记忆”:如何用数学揭开历史的足迹》 目录 《石头台阶的“记忆”:如何用数学揭开历史的足迹》 ✨摘要✨ ✨引言✨ 1. 引言的结构 2. 撰写步骤 (1)研究背景 &#…...
python远程获取数据库中的相关数据并存储至json文件
1. conn中的5个变量的含义: ① Driver:数据库驱动程序,我使用的是SQL Server数据库。 ② Server:数据库所在的服务器地址。 ③ Database:要连接的数据库的名称。 ④ UID:登录 SQL Server 数据库的用户名…...
DeepSeek-R1解读:纯强化学习,模型推理能力提升的新范式?
DeepSeek-R1解读:纯强化学习,模型推理能力提升的新范式? 1. Impressive Points2. 纯强化学习,LLM推理能力提升新范式?2.1 DeepSeek-R1-Zero2.2 DeepSeek-R1 3. 端侧模型能力提升:蒸馏>强化学习 1. Impre…...
系统安全及应用
一:账号安全控制 1.1 系统账号清理 1.1.1 将非登陆用户的Shell 设置为 /sbin/nologin (设置为这个解释器,禁止用户登陆) [rootlocalhost ~]# usermod -s /sbin/nologin zhangsan #将用户zhangsan 的登录解释器 设置为 /sbin/n…...
ubuntu解决普通用户无法进入root
项目场景: 在RK3566上移植Ubuntu20.04之后普通用户无法进入管理员模式 问题描述 在普通用户使用sudo su试图进入管理员模式的时候报错 解决方案: 1.使用 cat /etc/passwd 查看所有用户.最后一行是 若无用户,则使用 sudo useradd -r -m -s /…...
Mac m1,m2,m3芯片使用nvm安装node14报错
使用nvm安装了node 12/16/18都没有问题,到14就报错了。第一次看到这个报错有点懵,查询资料发现是Mac芯片的问题。 Issue上提供了两个方案: 1、为了在arm64的Mac上安装node 14,需要使用Rosseta,可以通过以下命令安装 …...
IDEA工具下载、配置和Tomcat配置
1. IDEA工具下载、配置 1.1. IDEA工具下载 1.1.1. 下载方式一 官方地址下载 1.1.2. 下载方式二 官方地址下载:https://www.jetbrains.com/idea/ 1.1.3. 注册账户 官网地址:https://account.jetbrains.com/login 1.1.4. JetBrains官方账号注册…...
实战网络安全:渗透测试与防御指南
📝个人主页🌹:一ge科研小菜鸡-CSDN博客 🌹🌹期待您的关注 🌹🌹 引言 在数字化时代,网络安全已成为企业和个人不可忽视的重要课题。网络攻击的复杂性与日俱增,从数据泄露…...
Vue 3 中的 toRef 与 toRefs:使用与案例解析
在 Vue 3 的响应式系统中,toRef 和 toRefs 是两个非常实用的工具函数。它们主要用于将响应式对象的属性转换为单独的 ref,以便在模板或逻辑中更方便地使用。本文将详细介绍 toRef 和 toRefs 的用法,并通过一个老师信息的案例来演示它们的实际…...
如何让Dev-C++支持C++11及以上标准
目录 问题描述解决方案步骤1:打开编译选项 问题描述 在Dev-C中使用C11/17/20新特性(如pop_back()等)时,可能出现编译错误: #include <iostream> #include<string> using namespace std; int main() {str…...
java8-日期时间Api
目录 LocalDate更新时间LocalTimeLocalDateTimeInstantPeriod Duration格式化、解析日期-时间对象时区 java.util.Date java.util.Calendar 不支持时区 线程不安全 月份从0起线程不安全,只有包裹在ThreadLocal中才安全 java.text.DateFormat java.text.SimpleDateFo…...
电脑无法开机,重装系统后没有驱动且驱动安装失败
电脑无法开机,重装系统后没有驱动且驱动安装失败 前几天电脑突然坏了,电脑卡住后,强制关机,再开机后开机马上就关机。尝试无数次开机后失败,进入BIOS界面,发现已经没有Windows系统了。重新安装系统后&…...
Vue.js 传递路由参数和查询参数
Vue.js 传递路由参数和查询参数 在 Vue.js 开发中,Vue Router 提供了灵活的方式来处理路由参数和查询参数,使得组件能够根据不同的路径或查询条件渲染相应的内容。 路由参数 路由参数(也称为路径参数)是 URL 路径的一部分&…...
Java 反射机制介绍
Java学习资料 Java学习资料 Java学习资料 一、引言 在 Java 编程里,反射机制是一项强大且独特的特性。它赋予程序在运行时动态地获取类的信息,并且可以操作类或对象的属性、方法和构造函数等。借助反射机制,程序的灵活性和可扩展性得到显著…...
Final2x--开源AI图片放大工具
Final2x--开源AI图片放大工具 链接:https://pan.xunlei.com/s/VOHSklukQAquUn3GE7eHJXfOA1?pwdr3r3#...
TCP全连接队列
1. 理解 int listen(int sockfd, int backlog) 第二个参数的作用 backlog:表示tcp全连接队列的连接个数1。 如果连接个数等于backlog1,后续连接就会失败,假设tcp连接个数为0,最大连接个数就为1,并且不accept获取连接…...
前端力扣刷题 | 4:hot100之 子串
560. 和为K的子数组 给你一个整数数组 nums 和一个整数 k ,请你统计并返回 该数组中和为 k 的子数组的个数 。 子数组是数组中元素的连续非空序列。 示例: 输入:nums [1,1,1], k 2 输出:2 法一:暴力法 var subar…...
【精选】基于数据挖掘的招聘信息分析与市场需求预测系统 职位分析、求职者趋势分析 职位匹配、人才趋势、市场需求分析数据挖掘技术 职位需求分析、人才市场趋势预测
博主介绍: ✌我是阿龙,一名专注于Java技术领域的程序员,全网拥有10W粉丝。作为CSDN特邀作者、博客专家、新星计划导师,我在计算机毕业设计开发方面积累了丰富的经验。同时,我也是掘金、华为云、阿里云、InfoQ等平台…...
字节跳动发布UI-TARS,超越GPT-4o和Claude,能接管电脑完成复杂任务
每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗?订阅我们的简报,深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同,从行业内部的深度分析和实用指南中受益。不要错过这个机会,成为AI领…...
2025课题推荐——USBL和DVL的误差建模与补偿
在海洋探测与研究中,定位技术的准确性至关重要。超短基线(USBL)和多普勒速度计(DVL)是两种广泛应用于水下定位和导航的技术,它们在深海探测、海洋工程和水下机器人等领域发挥着重要作用。然而,这…...
mysql_use_result的概念和使用案例
mysql_use_result 是 MySQL C API 中的一个函数,它用于检索一个结果集,并且不同于 mysql_store_result,它不会立即将整个结果集读入客户端。相反,它会初始化一个结果集,客户端随后可以通过调用 mysql_fetch_row 来逐行…...