[杂学笔记]锁为什么影响效率、I/O多路复用、三种I/O多路复用模型的区别、atomic原子操作类、MySQL的持久性是如何实现的

ops/2025/3/24 6:57:48/

目录

1.锁为什么影响效率

2.I./O多路复用

3.三种I/O多路复用模型的区别

4.atomic原子操作类

介绍

常用函数

内存顺序含义 

5.MySQL持久性的实现


1.锁为什么影响效率

  • 线程阻塞与上下文切换:在多线程并发访问的场景下,只有一个线程能够进入临界区进行操作,其他的线程都需要进行等待锁资源。那么线程阻塞的话,从运行状态切换到等待状态会涉及到线程的上下文切换,普通的线程调度来说上线文切换影响不大,但是对于锁竞争的时候,可能切换了好多次都没有获取到锁资源,那么就会频繁的进行上下文的切换,尤其是在高并发场景下,会增加非常大的系统开销。
  • 锁粒度的控制:锁的粒度是指被锁保护的资源范围,如果粒度过大的话,会将过多的不必要的资源放入保护范围内,会导致并发度降低很多。
  • 还有就是代码难度较高,可能会产生死锁的风险。

2.I./O多路复用

        I/O多路复用通常用于高效的处理多个I/O流,使得一个进程或者线程可以同时监控多个文件描述符的状态变化,而无需为每一个I/O流都分配一个单独的进程或线程。提高了系统资源的利用率,尤其是在高并发场景下,可以使用有限的资源处理更多的任务。

        在实现上,I/O多路复用是通过一个进程或线程,利用特定的系统调用select、poll、epoll模型,来监控多个文件描述符。当其中一个或多个文件描述符就绪的时候,系统调用就会返回,程序就可以根据返回的信息进行相应的I/O操作了。这样的话一个进程或者线程就可以同时处理多个I/O流,而不是只阻塞在某个特定的I/O操作上。

        同时I/O多路复用配合多线程的话,还可以使得等待与I/O操作进行分离,一批线程只负责I/O多路复用技术下的I/O事件监测操作,另一批线程对于就绪的事件进行相应的处理。这样的话,监测的线程可以时时刻刻的检测,不会有在处理I/O的时候,其他就绪的I/O事件无法及时处理的问题了。

3.三种I/O多路复用模型的区别

        select模型:首先他监控的文件描述符的数量是有限的,受到FD_SETSIZE字段值的限制,一般Linux平台下是1024,他规定了fd_set位图的最大长度。所以说他最多一次只能监控1024个文件描述符。而且他采用的是轮询方式检测哪些文件描述符就绪了,性能会有所下降。而且他传入的参数是输入输出型参数,所以如果像循环检测一批文件描述符的事件的,需要每一次调用select的时候重新传入我们想要监控的文件描述符对应想要监控的事件。

        poll模型:和select不同在于他的文件描述符监控的数量没有限制了,而且他也不用每一次都重新的设置想要监控的事件了。但是对于文件描述符的监控,还是采用的轮询检测,不在有文件描述符个数的约束的话,文件描述符数量庞大的时候,轮询检测会更加影响效率。

        epoll模型:就解决了上述的三个问题,第一个文件描述符有限制。第二个:传参麻烦的问题。第三个:轮询检测的问题。因为epoll模型的底层实现是通过中断或信号的方式来通知I/O事件就绪了,然后去对比是否是用户要监控的事件,如果是就放入到就绪队列中并返回即可。这一系列操作都是中断或者信号触发了回调函数完成的。

        同时epoll模型还支持LT与ET模式,LT模式是水平付出模式,一个文件描述符事件就绪了,如果上层不进行处理的话,那么epoll就会一直有事件就绪,就会一直返回通知上层。而ET模式则是边缘触发,相当于只通知一次,处不处理是上层的事情,反正epoll是通知了。那么这样也会倒逼着上层在事件就绪的时候,就及时的处理。

4.atomic原子操作类

介绍

        在 C++ 中,std::atomic 是标准库提供的用于实现原子操作的模板类,它可以保证在多线程环境下对共享数据的操作是原子的,从而避免数据竞争问题,且不需要显式使用锁机制。该类可以被看做是一个T类型的值,对该值的所有操作都是原子的。

常用函数

构造函数:

atomic (T val) noexcept;

存储操作:

void store (T val, memory_order sync = memory_order_seq_cst)

获取值操作:

T load (memory_order sync = memory_order_seq_cst)

替换操作:

T exchange (T val, memory_order sync = memory_order_seq_cst)

 算术操作:

T fetch_add (T val, memory_order sync = memory_order_seq_cst) 

T fetch_sub (T val, memory_order sync = memory_order_seq_cst)

T operator++() 

T operator--() 

T operator++(int) 

T operator--(int) 

内存顺序含义 

        上述常见的操作函数中,都有一个memory_order类型的参数,这个参数是用来指定原子操作的同步语义与内存的可见性的。不同的内存顺序会影响百年一起和处理器对指令的重排以及数据大的可见性。

  • std::memory_order_relaxed参数:这个参数仅仅只能保证操作的原子性,不会提供任何的同步机制,该操作指令会由系统自动的排序选择合适的时候处理。那么就可能导致,第一行代码的原子操作执行的时间晚于第二行代码。
  • std::memory_order_release参数:常用于存储的操作如store,该参数保证了该存储操作之前的所有读写操作必须先执行,不能放到该存储操作的后面。保证了顺序性。
  • std::memory_order_acquire参数:常用于加载操作如load,保证加载操作之后的所有读写操作都要后执行,不能重排到前面。
  • std::memory_order_seq_cst参数:默认的内存顺序,也是最高的同步,保证所有线程看到的操作顺序是一致的,就好像所有的操作都是在按顺序依次进行执行的。那么也必然需要内部增加更多的同步操作,所以会有一定的性能开销。

5.MySQL持久性的实现

        MySQL 的持久性是指一旦事务提交,其对数据库所做的修改就会永久保存,即使发生系统崩溃、断电等情况,数据也不会丢失。永久保存意味着要刷新到磁盘上,但是呢如果没进行一次事务的操作就刷新到磁盘上一次,那么会极大的影响效率了。

        所以MySQL引入了重做日志的概念,每次执行事务的时候,会将修改的操作记录到重做日志缓冲区,然后适当的事件刷新到磁盘的重做日志文件当中。这样,在系统崩溃的时候,会根据重做日志文件中的记录,将那么已经提交但是没有刷新到磁盘的数据恢复并刷新到磁盘中。保证数据的持久性。

        因为重做日志记录的是修改的操作,如不是真实的数据,所以相当来说数据量会小很多,而且日志是一条一条的顺序添加即可,而刷新数据到磁盘会涉及到查找数据位置,如果比较分散的话开销会比较大。而日志数据体量小,而且是顺序I/O,所以可以适当的增加刷新到磁盘的频率。而真正的数据则是需要定期的去刷新才不会影响MySQL的整体效率的同时,还能够将数据持久化。


http://www.ppmy.cn/ops/167752.html

相关文章

C/S模型-TCP

下图是基于TCP协议的客户端/服务器程序的一般流程: TCP协议通讯流程 服务器调用socket()、bind()、listen()完成初始化后,调用accept()阻塞等待,处于监听端口的状态,客户端调用socket()初始化后,调用connect()发出SY…

理解 Node.js 中的 process`对象与常用操作

理解 Node.js 中的 process 对象与常用操作 在 Node.js 中,process 是一个全局对象,提供了与当前 Node.js 进程相关的信息和操作。无论是获取进程信息、处理信号、访问环境变量,还是控制进程行为,process 都是不可或缺的工具。 看…

二次向用户申请授权

HarmonyOS 5.0.3(15) 版本的配套文档,该版本API能力级别为API 15 Release 文章目录 当应用通过requestPermissionsFromUser()拉起弹框请求用户授权时,用户拒绝授权。应用将无法再次通过requestPermissionsFromUser()拉起弹框,需要用户在系统应…

【Linux】交叉编译2

一、文章背景 疑惑 官方提供的SDK包的结构如下: hugohugo-virtual-machine:~$ tree -L 2 SDK SDK ├── environment-setup-aarch64-poky-linux ├── site-config-aarch64-poky-linux ├── sysroots │ ├── aarch64-poky-linux │ ├── aarch64-poky-li…

如何通过Python实现自动化任务:从入门到实践

在当今快节奏的数字化时代,自动化技术正逐渐成为提高工作效率的利器。无论是处理重复性任务,还是管理复杂的工作流程,自动化都能为我们节省大量时间和精力。本文将以Python为例,带你从零开始学习如何实现自动化任务,并通过一个实际案例展示其强大功能。 一、为什么选择Pyt…

设计模式,如单例模式、观察者模式在什么场景下使用

以下是单例模式和观察者模式的介绍及应用场景: 单例模式 - 定义:保证一个类仅有一个实例,并提供一个全局访问点。 - 实现方式:私有化构造函数,防止外部实例化;提供一个静态成员函数来获取唯一实例。 - 应用…

STM32 —— 嵌入式系统、通用计算机系统、物联网三层架构

目录 一、嵌入式系统的概念 二、通用计算机系统与嵌入式系统的比较 用途 硬件 软件 性能与功耗 开发与维护 三、嵌入式系统与物联网的关系 四、物联网的三层架构 1. 感知层(Perception Layer) 2. 网络层(Network Layer) …

针对耳鸣患者推荐的一些菜谱和食材

耳鸣患者应当关注饮食的均衡性,因为许多食物和营养素都可能对改善听力问题产生积极影响。以下是针对耳鸣患者推荐的一些菜谱和食材,以供参考。 一、蔬菜类 1. 菠菜:菠菜富含铁元素,对于补血益气有良好效果,能改善因贫…