基于进程信号量的多线程同步机制研究与实现
1 信号量
1.1 原理与概念
信号量机制本质是对于资源的预订操作,线程或者进程预订了之后,确保未来有一段时间,资源是属于我的。
对于预订资源,会有一个最小单位,资源都是以这个最小单位为整体被使用的。
信号量需要做到:
- 限制进来的进程数(保证每一个进来请求使用资源的进程都有一块资源)
- 合理的分配资源
这里,由于是信号量的前导,我们简单的把信号量理解为一个计数器(是由OS维护的)。
我们这里对于这个信号量的计数器的设计,提出几个问题?
1.计数器能不能简单的设计成一个整型变量?
不行,因为整型变量在经过进程创建之后,任意一个进程对他进行改变的时候,会发生写时拷贝,导致两个进程看到的不是同一个计数器,这样信号量的第一个目的,限制进入的进程数也就失效了。
2.count++和count--不是原子的。
3.申请sem和释放sem来保护临界资源,是规则。这个规则的由来?
这个规则就是,程序员之间规定的规则,再使用多进程访问临界资源的时候,需要代码这样来保护临界资源。
4.所有的进程要访问临界资源,都需要先申请信号量,那么所有进程都需要看到同一个信号量,说明了信号量本身就是一个临界资源。那么我们需要利用临界资源去保护另一个临界资源,为了防止临界资源保护的嵌套,我们就需要保证信号量这个临界资源是安全的。
所以,信号量的申请(++)和信号量的释放(--)这两个操作都是原子的。
5.如果,信号量的初始值是1?
那么,这个信号量不就是一个二元信号量(不就是一把锁吗)
6.我们前面提到了信号量也需要合理的分配资源,那么由谁来做呢?
这里,也是由程序员,在代码部分来完成这项目标。
7.pv操作
我们把原子性的申请信号量称为p操作,原子性的释放信号量称为v操作。
2 信号量的接口
2.1 初始化信号量:sem_init()
sem_init是Posix信号量操作中的一个函数,用于初始化一个定位在sem的匿名信号量。以下是对sem_init函数的详细解析:
一、函数原型
二、参数说明
- sem:指向sem_t类型的信号量对象的指针,该对象将被初始化。
- pshared:指明信号量的共享属性。如果其值为0,则信号量将被进程内的线程共享;如果其值为非零,则信号量将在进程之间共享,此时信号量应定位在共享内存区域中。
- value:指定信号量的初始值。这个值表示信号量可用的资源数目或信号灯的数目。
三、返回值
- 成功时,sem_init函数返回0。
- 失败时,sem_init函数返回-1,并将errno设置为合适的值以指示错误原因。
四、注意事项
- 初始化一个已经初始化的信号量,其结果未定义。因此,在调用sem_init之前,应确保信号量对象未被初始化。
- 当pshared为非零时,信号量必须存在于共享内存中,否则无法实现进程间共享。
- 使用完信号量后,应调用sem_destroy函数来销毁它,以释放相关资源。
2.2 信号量等待:sem_wait()
sem_wait
是 POSIX 信号量(semaphore)API 中的一个函数,用于对信号量进行 (wait/down)操作。这个函数会阻塞调用它的线程,直到信号量的值大于零,然后它会将信号量的值减一并继续执行。如果信号量的值已经是零,则调用 sem_wait
的线程会被阻塞,直到信号量的值被其他线程通过 sem_post
增加。
一、函数原型
二、参数
sem
:指向sem_t
类型的信号量对象的指针。这个信号量对象应该是之前通过sem_init
或sem_open
初始化的。
三、返回值
- 成功时,
sem_wait
返回 0。 - 失败时,
sem_wait
返回 -1,并设置errno
来指示错误的原因。可能的错误包括EINVAL
(无效的参数,即sem
不是有效的信号量),EINTR
(操作被信号中断),EDEADLK
(死锁条件,如果信号量是通过sem_init
初始化为线程间共享且调用线程已经拥有该信号量),以及ENOSYS
(如果系统不支持这个操作,尽管在现代 POSIX 系统中这不太可能)。
四、使用场景
sem_wait
通常用于保护临界区(critical section),确保同一时间只有一个线程(或进程,取决于信号量的共享属性)可以进入和执行临界区内的代码。这有助于避免多线程程序中的竞态条件(race conditions)和数据不一致问题。
五、注意事项
- 在调用
sem_wait
之前,应确保信号量已经被正确初始化。 - 如果信号量被设置为线程间共享(
sem_init
的pshared
参数非零),则所有操作该信号量的线程都应该在同一个进程内,或者信号量应该位于共享内存区域中,以便在不同进程间共享。 - 在不再需要信号量时,应调用
sem_destroy
来销毁它(对于通过sem_init
初始化的信号量)或sem_close
和sem_unlink
(对于通过sem_open
创建的命名信号量)。
2.3 信号量申请:sem_post
sem_post
是 POSIX 信号量(semaphore)API 中的一个函数,用于对信号量进行 V(signal/up)操作。这个函数会增加信号量的值,并可能唤醒一个或多个因为调用 sem_wait
而被阻塞的线程。
一、函数原型
二、参数
sem
:指向sem_t
类型的信号量对象的指针。这个信号量对象应该是之前通过sem_init
(对于匿名信号量)或sem_open
(对于命名信号量)初始化的。
三、返回值
- 成功时,
sem_post
返回 0。 - 失败时,
sem_post
返回 -1,并设置errno
来指示错误的原因。可能的错误包括EINVAL
(无效的参数,即sem
不是有效的信号量)。
四、使用场景
sem_post
通常与 sem_wait
一起使用,以实现线程间的同步。当一个线程完成了对临界区的访问后,它会调用 sem_post
来增加信号量的值,从而可能允许其他被阻塞的线程进入临界区。
五、注意事项
- 在调用
sem_post
之前,应确保信号量已经被正确初始化。 - 如果信号量被设置为线程间共享(
sem_init
的pshared
参数非零),则所有操作该信号量的线程都应该在同一个进程内,或者信号量应该位于共享内存区域中,以便在不同进程间共享。然而,需要注意的是,POSIX 信号量 API 并不直接支持跨进程的匿名信号量;跨进程共享通常是通过命名信号量(使用sem_open
)来实现的。 sem_post
的操作是原子的,即它不会被其他线程的sem_wait
或sem_trywait
调用中断。
2.4 信号量销毁:sem_destroy()
sem_destroy
是 POSIX 信号量(semaphore)API 中的一个函数,用于销毁一个由 sem_init
初始化的匿名信号量。这个函数会释放与信号量相关联的任何资源,并且只有在没有线程等待该信号量时才能成功调用。
一、函数原型
二、参数
sem
:指向sem_t
类型的信号量对象的指针。这个信号量对象应该是之前通过sem_init
初始化的。
三、返回值
- 成功时,
sem_destroy
返回 0。 - 失败时,
sem_destroy
返回 -1,并设置errno
来指示错误的原因。可能的错误包括EBUSY
(信号量当前正在被使用,即有线程正在等待它),以及EINVAL
(无效的参数,即sem
不是有效的信号量)。
四、使用场景
sem_destroy
应该在信号量不再需要时被调用,以释放与其相关联的资源。这通常发生在程序结束或信号量完成其同步任务之后。
五、注意事项
- 在调用
sem_destroy
之前,应确保没有线程在等待该信号量。如果有线程在等待,sem_destroy
将返回 -1 并设置errno
为EBUSY
。 sem_destroy
只能用于由sem_init
初始化的匿名信号量。对于通过sem_open
创建的命名信号量,应使用sem_close
和sem_unlink
来关闭和删除它们。- 一旦信号量被销毁,就不能再对它进行任何操作(如
sem_wait
、sem_post
等),否则会导致未定义的行为。
相关文章:
基于进程信号量的多线程同步机制研究与实现
1 信号量 1.1 原理与概念 信号量机制本质是对于资源的预订操作,线程或者进程预订了之后,确保未来有一段时间,资源是属于我的。 对于预订资源,会有一个最小单位,资源都是以这个最小单位为整体被使用的。 信号量需要做…...
七、队列————相关概念详解
队列————相关概念详解 前言一、队列1.1 队列是什么?1.2 队列的类比 二、队列的常用操作三、队列的实现3.1 基于数组实现队列3.1.1 基于环形数组实现的队列3.1.2 基于动态数组实现的队列 3.2 基于链表实现队列 四、队列的典型应用总结 前言 本篇文章,我们一起来…...
钉钉h5微应用鉴权配置客户端 API 鉴权步骤
这里记录一下使用的钉钉h5微应用 配置客户端 API 鉴权的内容 注意不是所有的都功能都需要鉴权。 先要引入钉钉环境 见下链接 https://blog.csdn.net/KLS_CSDN/article/details/144794982?spm1001.2014.3001.5501 引入鉴权代码到前端页面并配置以下参数: dd.con…...
04.HTTPS的实现原理-HTTPS的混合加密流程
04.HTTPS的实现原理-HTTPS的混合加密流程 简介1. 非对称加密与对称加密2. 非对称加密的工作流程3. 对称加密的工作流程4. HTTPS的加密流程总结 简介 主要讲述了HTTPS的加密流程,包括非对称加密和对称加密两个阶段。首先,客户端向服务器发送请求…...
Python中构建终端应用界面利器——Blessed模块
在现代开发中,命令行应用已经不再仅仅是一个简单的文本输入输出工具。随着需求的复杂化和用户体验的重视,终端界面也逐渐成为一个不可忽视的设计环节。 如果你曾经尝试过开发终端UI,可能对传统的 print() 或者 input() 函数感到不满足&#…...
【Python】 基于Python实现日志聚合与分析工具:利用Logstash与Fluentd构建高效分布式日志系统
《Python OpenCV从菜鸟到高手》带你进入图像处理与计算机视觉的大门! 解锁Python编程的无限可能:《奇妙的Python》带你漫游代码世界 在分布式系统中,日志数据的生成速度和数量呈指数级增长,传统的日志管理方式已无法满足现代企业对实时性、可扩展性和高效性的需求。本文深…...
汽车网络安全基线安全研究报告
一、引言 随着汽车行业朝着智能网联方向飞速发展,汽车网络安全已成为保障用户安全和行业健康发展的关键要素。本报告将深入探讨汽车网络安全相关内容,以及国际、国内重要的汽车网络安全标准基线和相应防护措施等内容。 二、汽车网络安全的重要性 &…...
[pdf、epub]260道《软件方法》强化自测题业务建模需求分析共216页(202412更新)
DDD领域驱动设计批评文集 做强化自测题获得“软件方法建模师”称号 《软件方法》各章合集 260道《软件方法》强化自测题业务建模需求分析共216页(202412更新) 已上传到本CSDN账号的资源 如果下载不到,也可以访问以下链接: ht…...
工业4.0和MES(制造执行系统)方案(附实践资料)
工业4.0和MES(制造执行系统)方案是智能制造领域中的关键组成部分,它们共同推动着制造业的数字化转型。以下是工业4.0和MES方案的一些核心要点: 智能制造背景: 工业4.0是第四次工业革命,它结合了信息通信技术…...
机器视觉中的单线程、多线程与跨线程:原理与应用解析
在机器视觉应用中,程序的运行效率直接影响到系统的实时性和稳定性。随着任务复杂度的提高,单线程处理往往无法满足高性能需求,多线程技术因此被广泛应用。此外,跨线程操作(如在多线程中更新界面或共享资源)…...
性能测试瓶颈:CPU 问题的深度分析和调优
🍅 点击文末小卡片 ,免费获取软件测试全套资料,资料在手,涨薪更快 我们做性能测试的时候,除了使用工具编写脚本并执行之外,最核心的工作就是做性能测试结果分析和问题调优。然后在做性能测试的时候…...
云手机与Temu矩阵:跨境电商运营新引擎
云手机与 Temu 矩阵结合的基础 云手机技术原理 云手机基于先进的 ARM 虚拟化技术,在服务器端运行 APP。通过在服务器上利用容器虚拟化软件技术,能够虚拟出多个独立的手机操作系统实例,每个实例等同于一部单独的手机,可独立运行各…...
Oracle考试多少分算通过?
OCP和OCM认证的考试及格分数并不是固定的,而是根据考试的难度和考生的整体表现来确定。对于OCP认证,考生需要全面掌握考试要求的知识和技能,并在考试中表现出色才有可能通过。而对于OCM认证,考生则需要在每个模块中都达到一定的水…...
【UE5.3.2】安装metahuman插件
Unable to find plugin ‘MetaHuman’报错 Unable to find plugin MetaHuman (referenced via RPect_5_3.uproject). Install it and try again, or remove it from the required plugin list. 10>Microsoft.MakeFile.Targets(44,5): Error MSB3073 :...
python lambda函数用法
在Python中,lambda函数是一种用于创建匿名函数的简便方式。它允许你快速定义一个简单的函数,而不需要使用传统的def语句。lambda函数通常用于一次性的操作或作为参数传递给其他函数。 lambda函数的语法: lambda 参数1, 参数2, ... : 表达式l…...
acitvemq AMQP:因为消息映射策略配置导致的MQTT接收JMS消息乱码问题 x-opt-jms-dest x-opt-jms-msg-type
使用ActiveMQ(5.14.5)作消息系统服务的场景下, 当我用Apache Qpid Proton发送消息(使用AMQP协议)发送JMS消息,用Paho MQTT接收消息的时候, 收到的消息前面总是有一串乱码,大概就是这样: 4Sp?AS…...
ida的使用
一.ida的基本设置 在IDA的安装根目录下有许多文件夹,各个文件夹存储不同的内容 1.目录结构 cfg:包含各种配置文件,基本IDA配置文件ida.cfg,GUI配置文件idagui.cfg,文本模式用户界面配置文件idatui.cfg, idc:包含…...
archery docker安装
#下载Archery-1.11.3.tar.gz https://codeload.github.com/hhyo/Archery/tar.gz/refs/tags/v1.11.3 cd /root tar -zxvf Archery-1.11.3.tar.gz cd /root/Archery-1.11.3/src/docker-compose #启动 docker compose -f docker-compose.yml up -d#表结构初始化 docker exec -ti a…...
【zookeeper核心源码解析】第四课:客户端与服务端读写的io核心流程
系列文章目录 【zookeeper核心源码解析】第一课:zk启动类核心流程序列图 【zookeeper核心源码解析】第二课:俯瞰QuorumPeer启动核心流程,实现选举关键流程 【zookeeper核心源码解析】第三课:leader与follower何时开始同步&#…...
影刀进阶指令 | Kimi (对标ChatGPT)
文章目录 影刀进阶指令 | Kimi (对标ChatGPT)一. 需求二. 流程三. 实现3.1 流程概览3.2 流程步骤讲解1\. 确定问题2\. 填写问题并发送3\. 检测答案是否出完 四. 运维 影刀进阶指令 | Kimi (对标ChatGPT) 简单讲讲RPA调用kimi实现…...
Linux第99步_Linux之点亮LCD
主要学习如何在Linux开发板点亮屏,以及modetest命令的实现。 很多人踩坑,我也是一样。关键是踩坑后还是实现不了,这样的人确实很多,从群里可以知道。也许其他人没有遇到这个问题,我想是他运气好。 1、修改设备树 1)、…...
【C++决策和状态管理】从状态模式,有限状态机,行为树到决策树(三):基于BT行为树实现复杂敌人BOSS-AI
前言 (题外话)nav2系列教材,yolov11部署,系统迁移教程我会放到年后一起更新,最近年末手头事情多,还请大家多多谅解。回顾我们整个学习历程,我们已经学习了很多C的代码特性,也学习了很多ROS2的跨…...
SpringCloudAlibaba技术栈-Higress
1、什么是Higress? 云原生网关,干啥的?用通俗易懂的话来说,微服务架构下Higress 就像是一个智能的“交通警察”,它站在你的网络世界里,负责指挥和调度所有进出的“车辆”(也就是数据流量)。它的…...
《信息传播:人工智能助力驱散虚假信息阴霾》
在信息爆炸的时代,虚假信息和谣言如同脱缰野马,肆意传播,对社会秩序和公众生活造成了严重影响。人工智能作为一种强大的技术工具,正逐渐成为信息传播的有力助手,为防止虚假信息和谣言扩散提供了新的途径。 虚假信息和…...
玩客云v1.0 刷机时无法识别USB
v1.0刷机时公对公插头掉了,刷机失败,再次刷机,一直提示无法识别的USB设备,此时LED一直不亮,就像是刷成砖了一样,查了好多文章最后发现正面还有一个地方需要短接。 背面的短接点 【免费】玩客云刷机包s805-…...
STM32F103RCT6学习之五:ADC
1.ADC基础 ADC(Analog-Digital Converter)模拟-数字转换器ADC可以将引脚上连续变化的模拟电压转换为内存中存储的数字变量,建立模拟电路到数字电路的桥梁12位逐次逼近型ADC,1us转换时间 输入电压范围:0~3.3Vÿ…...
通过Cephadm工具搭建Ceph分布式存储以及通过文件系统形式进行挂载的步骤
1、什么是Ceph Ceph是一种开源、分布式存储系统,旨在提供卓越的性能、可靠性和可伸缩性。它是为了解决大规模数据存储问题而设计的,使得用户可以在无需特定硬件支持的前提下,通过普通的硬件设备来部署和管理存储解决方案。Ceph的灵活性和设计…...
flink+kafka实现流数据处理学习
在应用系统的建设过程中,通常都会遇到需要实时处理数据的场景,处理实时数据的框架有很多,本文将以一个示例来介绍flinkkafka在流数据处理中的应用。 1、概念介绍 flink:是一个分布式、高可用、高可靠的大数据处理引擎,…...
SpringBoot使用外置的Servlet容器(详细步骤)
嵌入式Servlet容器:应用打成可执行的jar 优点:简单、便携; 缺点:默认不支持JSP、优化定制比较复杂.; 外置的Servlet容器:外面安装Tomcat---应用war包的方式打包; 操作步骤: 方式一&…...
C# 中的委托与事件:实现灵活的回调机制
C#中的委托(Delegate)和事件(Event)。委托和事件是C#中非常重要的特性,它们允许你实现回调机制和发布-订阅模式,从而提高代码的灵活性和解耦程度。通过使用委托和事件,你可以编写更加模块化和可…...
大模型辅助测试的正确打开方式?
测试的基本目的之一,是对被测对象进行质量评估。换言之,是要提供关于被测对象质量的“确定性”。因此,我们很忌讳在测试设计中引入“不确定性”,比如采用不可靠的测试工具、自动化测试代码逻辑复杂易错、测试选择假设过于主观等等…...
设计模式之代理模式
代理模式代码示例:https://blog.csdn.net/weixin_39865508/article/details/141924680 代理模式的左右,一定程度上不暴露被代课对象的内容,更安全,也减少系统的耦合性 静态代理 代理对象和被代理对象都继承同一个接口 在代理对象…...
win11中win加方向键失效的原因
1、可能是你把win键锁了: 解决办法:先按Fn键,再按win键 2、可能是可能是 贴靠窗口设置 中将贴靠窗口关闭了,只需要将其打开就好了...
Html——11. 页面跳转
<!DOCTYPE html> <html><head><meta charset"UTF-8"><title>页面跳转</title><meta http-equiv"refresh" content"5; urlhttps://www.51zxw.net"/><!--<meta http-equiv"refresh" co…...
要查询 `user` 表中 `we_chat_open_id` 列不为空的用户数量
要查询 user 表中 we_chat_open_id 列不为空的用户数量,你可以使用以下 SQL 查询语句: SELECT COUNT(*) FROM user WHERE we_chat_open_id IS NOT NULL AND we_chat_open_id ! ;解释: SELECT COUNT(*): 表示要计算符合条件的行数。FROM us…...
docker-compos mysql5.7主从配置
docker-compos mysql5.7主从配置 docker-compose目录结构 配置文件 master/my.cnf [client] port 3306 socket /var/run/mysqld/mysqld.sock[mysqld_safe] pid-file /var/run/mysqld/mysqld.pid socket /var/run/mysqld/mysqld.sock nice 0…...
关于无线AP信道调整的优化(锐捷)
目录 一、信道优化的基本原则二、2.4G频段信道优化三、5G频段信道优化四、信道优化代码具体示例五、其他优化措施 一、信道优化的基本原则 信道优化旨在减少信道间的干扰,提高网络覆盖范围和信号质量。基本原则包括: 1. 选择合适的信道:根据…...
Flask入门一(介绍、Flask安装、Flask运行方式及使用、虚拟环境、调试模式、配置文件、路由系统)
文章目录 一、Flask介绍二、Flask创建和运行 1.安装2.快速使用3.Flask小知识4.flask的运行方式 三、Werkzeug介绍四、Jinja2介绍五、Click CLI 介绍六、Flask安装 介绍watchdog使用python–dotenv使用(操作环境变量) 七、虚拟环境 介绍Mac/linux创建虚拟…...
解决Docker国内网络问题
6月后以来,大量Docker镜像网站停服,Docker无法下载安装 本仓库致力于解决国内网络原因无法使用Docker的问题。 特点: 使用Github Action将官网的安装脚本/安装包定时下载到本项目Release,供国内使用官方安装包,安全可…...
Anaconda 安装与虚拟环境创建完整指南
Anaconda 安装与虚拟环境创建完整指南 Anaconda 是目前最流行的 Python 和数据科学工具集之一,它不仅可以轻松管理 Python 包,还能提供强大的虚拟环境功能,避免项目之间的依赖冲突。如果你是机器学习、数据科学或计算机视觉的开发者…...
【Java数据结构】LinkedList与链表
认识LinkedList LinkedList就是一个链表,它也是实现List接口的一个类。LinkedList就是通过next引用将所有的结点链接起来,所以不需要数组。LinkedList也是以泛型的方法实现的,所以使用这个类都需要实例化对象。 链表分为很多种,比…...
Linux 搭建 nginx+keepalived 高可用 | Nginx反向代理
注意:本文为 “Linux 搭建 nginxkeepalived (主备双主模式) 高可用 | Nginx反向代理” 相关文章合辑。 KeepalivedNginx实现高可用(HA) xyang0917 于 2016-09-17 00:24:15 发布 keepalived 的 HA 分为抢占模式和非抢占模式,抢占…...
17_HTML5 Web 存储 --[HTML5 API 学习之旅]
HTML5 Web 存储(Web Storage)是 HTML5 引入的一种在用户浏览器中存储数据的机制。它提供了比传统的 cookies 更加方便和强大的功能,包括更大的存储空间、更好的性能以及更简单的 API。Web 存储主要分为两种类型:localStorage 和 s…...
uni-app(优医咨询)项目实战 - 第7天
学习目标: 能够基于 WebSocket 完成问诊全流程 能够使用 uniCloud 云存储上传文件 能够完成查看电子处方的功能 能够完成医生评价的功能 一、问诊室 以对话聊天的方式向医生介绍病情并获取诊断方案,聊天的内容支持文字和图片两种形式。 首先新建一…...
今日总结 2024-12-28
今天全身心投入到鸿蒙系统下 TCPSocket 的学习中。从最基础的 TCP 协议三次握手、四次挥手原理重新梳理,深刻理解其可靠连接建立与断开机制,这是后续运用 TCPSocket 无误通信的根基。在深入鸿蒙体系时,仔细研读了其为 TCPSocket 封装的 API&a…...
ip归属地怎么判定?如何查看自己ip属地
在当今数字化时代,IP地址作为互联网通信的基础,扮演着至关重要的角色。而IP归属地的判定与查看,不仅关乎网络安全、隐私保护,还直接影响到社交平台的信任机制与信息传播的真实性。本文将深入探讨IP归属地的判定原理以及如何查看自…...
4.采用锁操作并支持等待功能的线程安全队列
分析 书接上文 修改push()似乎并不困难:在函数末尾加上对data_cond.notify_one()的调用即可,与代码清单1(第一篇文章)一样。事情其实没那么简单,我们之所以采用精细粒度的锁,目的是尽可能提高并发操作的数量。如果在notify_one()调用期间&a…...
螺杆支撑座在运用中会出现哪些问题?
螺杆支撑座是一种用于支撑滚珠螺杆的零件,通常用于机床、数控机床、自动化生产线等高精度机械设备中。在运用中可能会出现多种问题,这些问题源于多个方面,以下是对可能出现的问题简单了解下: 1、安装不当:安装过程中没…...
OSI 七层模型 | TCP/IP 四层模型
注:本文为 “OSI 七层模型 | TCP/IP 四层模型” 相关文章合辑。 未整理去重。 OSI 参考模型(七层模型) BeretSEC 于 2020-04-02 15:54:37 发布 OSI 的概念 七层模型,亦称 OSI(Open System Interconnection…...
秒鲨后端之MyBatis【2】默认的类型别名、MyBatis的增删改查、idea中设置文件的配置模板、MyBatis获取参数值的两种方式、特殊SQL的执行
别忘了请点个赞收藏关注支持一下博主喵!!!! ! ! 下篇更新: 秒鲨后端之MyBatis【3】自定义映射resultMap、动态SQL、MyBatis的缓存、MyBatis的逆向工程、分页插件。 默认的类型别名 MyBatis的增删改查 添加 <!--int insertUs…...