Linux开发
文章平均质量分 93
Linux服务器开发
C/C++Linux后台服务器开发高级架构师内容包括C/C++,Linux,Nginx,ZeroMQ,MySQL,Redis,MongoDB,ZK,流媒体,音视频开发,Linux内核,TCP/IP,协程,DPDK多个高级知识点。
展开
-
「AVL平衡树专项」带你领略常用的AVL树与红黑树的奥秘(规则篇)
满足下列条件的二叉搜索树是红黑树每个结点要么是“红色”,要么是“黑色”所有的叶结点都是空结点,并且是“黑色”的。如果一个结点是“红色”的,那么它的两个子结点都是“黑色”的。(注:也就是說,如果結點是黑色的,那么它的子節點可以是紅色或者是黑色的)。结点到其子孙结点的每条简单路径都包含相同数目的“黑色”结点根结点永远是“黑色”的之所以称为红黑树的原因就在于它的每个结点都被“着色”为红色或黑色。这些结点颜色被用来检测树的平衡性。原创 2023-02-04 14:49:53 · 599 阅读 · 0 评论 -
一文揭晓,我是如何在Linux中查找自如
以上操作我们能够通过 find 命令来查找结果,但更多时候我们真正想做的是对结果执行某些特殊操作。当我们想要删除 /Users/cbuc/testdir/dir2 这个目录时,我们可以通过以上认识到的操作先进行查找然后使用 -delete 命令来删除当前匹配的文件可以发现, /Users/cbuc/testdir/dir2 这个目录已经被删除了除了删除操作,还可以进行以下几种常见的操作:-delete:删除当前匹配的文件-ls:对匹配的文件执行相当于 ls -dils 命令的操作。原创 2023-02-01 16:55:32 · 322 阅读 · 0 评论 -
MySQL 中主从之间是怎样保证数据一致的呢?
今天,我们介绍了 MySQL 数据库主从复制过程中可能会遇到的一些问题。其中最主要的就是 binlog 日志在 STATEMENT 类型下有着存储数据量小的优点,但是也有导致数据不一致的情况;ROW 类型能够有效地解决数据不一致这种情况,但是也有存储数据量大这一缺点;MySQL 数据库结合前面两种类型的优点,又为我们提供了一个 mixed 类型。在日常的生产环境中,常用的 binlog 日志类型就是 mixed 类型。原文链接:MySQL 中主从之间是怎样保证数据一致的呢?原创 2023-01-31 16:04:34 · 1319 阅读 · 0 评论 -
树与二叉树深度剖析(二)
(1). 第一个节点先成为表示树的根(2). 第二个结点插入时变为根,原根结点变为新结点的左孩子。(3). 插入节点为数字时,沿根结点右链插入到最右端。(4). 插入节点为操作符时,先与根结点操作符优先级对比。a.优先级不高时,新结点成为根结点,原表达式成为新结点的左子树。b.优先级高时,新结点成为根结点的右孩子,原根结点的右孩子成为新结点的左子树。代码分享:/// 树节点类set;} //左孩子set;} //右孩子set;} //数据} //是否为操作符/// 数据构造。原创 2023-01-29 14:54:51 · 271 阅读 · 0 评论 -
树与二叉树深度剖析(一)
(1) 树结构是一种非线性存储结构,存储的是具有“一对多”关系的数据元素的集合。(2) 树(Tree)是n(n≥0)个节点(Node)的有限集合。在任意一颗非空树中,有且仅有一个特定的成为根(Root)的节点,当n>1时,其余节点分成m(m>0)个互不相交的有限集T1,T2,……,Tm,其中每一个集合本身又是一棵树,并且称为根的子树。树的定义是递归的,即在树的定义中又用到了树的概念,它刻画了树固有的特性,即一棵树有若干个子树构成,而子树又由更小的若干子树构成。原创 2023-01-28 16:13:43 · 584 阅读 · 0 评论 -
从状态机的角度async和await的实现原理
(1).含义:通常我们所说的状态机(State Machine)指的是有限状态自动机的简称,是现实事物运行规则抽象而成的一个数学模型,可以理解成一个状态转换图。(状态机是计算机科学的重要基础概念之一,也可以说是一种总结归纳问题的思想,应用范围非常广泛)(2).例子:自动门有两个状态,open 和 closed ,closed 状态下,如果读取开门信号,那么状态就会切换为 open。原创 2023-01-13 14:30:43 · 723 阅读 · 0 评论 -
高性能网关基石——OpenResty
这边推荐使用 xxx_by_lua_file,它彻底分离了配置文件与业务代码,让两者可以独立部署,而且文件形式也让我们更容易以模块的方式管理组织 Lua 程序。更多C++后台开发技术点知识内容包括C/C++,Linux,Nginx,ZeroMQ,MySQL,Redis,MongoDB,ZK,流媒体,音视频开发,Linux内核,TCP/IP,协程,DPDK多个高级知识点。【文章福利】另外还整理一些C++后台开发架构师 相关学习资料,面试题,教学视频,以及学习路线图,免费分享有需要的可以点击领取。原创 2023-01-04 14:59:25 · 1009 阅读 · 0 评论 -
Redis架构演变之主从、Sentinel哨兵、Cluster(通信、分片、路由等机制)
(1). 客户端分片方案A. 哈希取模:hash(key)% N,hash代表一种散列算法,N代表redis服务器的数量。这种算法实现起来非常简单,但是缺点也是非常明显的,当服务器数量N增加或者减少的时候,原先的缓存数据定位几乎失效,缓存数据定位失效意味着要到数据库重新查询,这对于高并发的系统来说是致命的。B. 一致性哈希算法:将key和server都进行hash,分配在闭环上,采用临近原则,key 找 离它最近的server节点进行存储。原创 2022-12-22 15:10:00 · 663 阅读 · 0 评论 -
消息中间件执行原理
消息中间件是指在分布式系统中完成消息的发送和接收的基础软件。消息中间件也可以称消息队列(Message Queue / MQ),用高效可靠的消息传递机制进行与平台无关的数据交流,并基于数据通信来进行分布式系统的集成。通过提供消息传递和消息队列模型,可以在分布式环境下扩展进程的通信。简而言之,互联网场景中经常使用消息中间件进行消息路由、订阅发布、异步处理等操作,来缓解系统的压力。原创 2022-12-21 14:40:34 · 619 阅读 · 0 评论 -
数据存储,消息队列的高可用保障
理解好RabbitMQ 中 Broker 存储的组成要素 CommitLog,ConsumeQueue,IndexFile。当 Broker 收到消息存储请求时,通过调用 CommitLog 对应的 MappedFile,把消息写入MappedFile的MeppedByteBuffer(内存映射)。原创 2022-12-20 14:49:48 · 199 阅读 · 0 评论 -
性能优化-内存泄漏、内存溢出、cpu占用高、死锁、栈溢出、FullGC频繁检测手段-总结与分享
含义:内层溢出通俗理解就是内存不够,程序要求的内存超出了系统所能分配的范围。危害:内存溢出错误会导致处理数据的任务失败,甚至会引发平台崩溃等严重后果。应用程序CPU使用率高,甚至超过100%死锁是指两个或两个以上的进程在执行过程中,由于竞争资源或者由于彼此通信而造成的一种阻塞的现象,若无外力作用,它们都将无法推进下去。此时称系统处于死锁状态或系统产生了死锁,这些永远在互相等待的进程称为死锁进程。Java 里的 StackOverflowError。抛出这个错误表明应用程序因为深递归导致栈被耗尽了。原创 2022-12-17 14:53:03 · 2054 阅读 · 2 评论 -
介绍四大并发集合类并结合单例模式下的队列来说明线程安全和非安全的场景及补充性能调优问题。
背景:我们目前使用的所有集合都是线程不安全的。:就是利用线程槽来分摊Bag中的所有数据,链表的头插法,0代表移除最后一个插入的值.(等价于同步中的List):线程安全的Stack是使用Interlocked来实现线程安全, 而没有使用内核锁.(等价于同步中的数组): 队列的模式,先进先出(等价于同步中的队列): 字典的模式(等价于同步中的字典)以上四种安全的并发集合类,也可以采用同步版本+Lock锁(或其它锁)来实现。原创 2022-12-16 15:06:11 · 229 阅读 · 0 评论 -
socket是并发安全的吗
1. 多线程并发读/写同一个TCP socket是线程安全的,因为TCP socket的读/写操作都上锁了。虽然线程安全,但依然不建议你这么做,因为TCP本身是基于数据流的协议,一份完整的消息数据可能会分开多次去写/读,内核的锁只保证单次读/写socket是线程安全,锁的粒度并不覆盖整个完整消息。因此建议用一个线程去读/写TCP socket。2. 多线程并发读/写同一个UDP socket也是线程安全的,因为UDP socket的读/写操作也都上锁了。原创 2022-12-15 16:23:37 · 254 阅读 · 0 评论 -
时间复杂度和空间复杂度
算法,即解决问题的方法。同一个问题,使用不同的算法,虽然得到的结果相同,但是耗费的时间和资源是不同的。就比如要拧一个螺母,使用扳手还是钳子是有区别的,虽然使用钳子也能拧螺母,但是没有扳手好用。“条条大路通罗马”,解决问题的算法有多种,这就需要判断哪个算法“更好”。原创 2022-12-12 15:13:06 · 146 阅读 · 0 评论 -
线性表→顺序表→链表 逐个击破
顺序表,全名"顺序存储结构",是线性表的一种。我们知道线性表是用来存储逻辑关系为 "一对一" 的数据,顺表也不例外。顺序表存储数据时,会提前申请一整块足够大小的物理空间,然后将数据依次存储起来,存储时做到数据元素之间不留一丝缝隙。例如,使用顺序表存储集合 {1,2,3,4,5},数据最终的存储状态如下图:由此我们可以得出,将“具有 '一对一' 逻辑关系的数据按照次序连续存储到一整块物理空间上”的存储结构就是顺序存储结构。顺序表存储数据同数组非常接近。其实,顺序表存储数据使用的就是数组。原创 2022-12-10 14:14:31 · 813 阅读 · 0 评论 -
Redis 为什么这么快,你知道 I/O 多路复用吗?
现在,我们知道啦,Redis 为什么快了吧。Redis 单线程是指在网络 I/O 和 键值的读写操作是有一个线程来完成的,采用单线程的好处是避免了多线程并发需要竞争获取锁。单线程之所以性能高效是因为其选择了 I/O 多路复用模型。搞懂了 select/epoll 这这些,慢慢会发现自己会逐渐比身边的伙伴优秀一些。原文链接:https://juejin.cn/post/7170712250880606221。原创 2022-12-09 14:39:29 · 204 阅读 · 0 评论 -
Redis缓存雪崩、击穿、穿透、双写一致性、并发竞争、热点key重建优化、BigKey的优化 等解决方案
在Redis中,一个字符串最大512MB,一个二级数据结构(例如hash、list、set、zset)可以存储大约40亿个(2^32-1)个元素,但实际中如果下面两种情况,我就会认为它是bigkey。(1). 字符串类型:它的big体现在单个value值很大,一般认为超过10KB就是bigkey。(2). 非字符串类型:哈希、列表、集合、有序集合,它们的big体现在元素个数太多。一般来说,string类型控制在10KB以内,hash、list、set、zset元素个数不要超过5000。原创 2022-12-08 14:50:31 · 2017 阅读 · 1 评论 -
Redis数据持久化机制(备份恢复)、缓存淘汰策略、主从同步原理、常见规范与优化详解
Redis 提供了 RDB 和 AOF 两种持久化方式,默认开启的是RDB,如果需要AOF,需要手动修改配置文件进行开启。 RDB:是一种对Redis存在内存中的数据周期性的持久化机制,将内存中的数据以快照的形式硬盘,实质上是fork了一个子进程在执行数据存储,采用的是二进制压缩的存储模式。如图: AOF:是以文本日志的形式记录Redis的每一个写入、删除请求(查询请求不处理),它是以追加的方式(append-only)写入,没有磁盘寻址的开销,所以写入速度非常快(类似mysql的binlog)。如图:(原创 2022-12-07 15:08:07 · 645 阅读 · 0 评论 -
Redis事务、pub/sub、PipeLine-管道、benchmark性能测试详解
(1). 原子性一个事务(transaction)中的所有操作,要么全部完成,要么全部不完成,不会结束在中间某个环节。事务在执行过程中发生错误,会被恢复(Rollback)到事务开始前的状态,就像这个事务从来没有执行过一样。 Redis的事务并不是我们传统意义上理解的事务,我们都知道 单个 Redis 命令的执行是原子性的,但 Redis 没有在事务上增加任何维持原子性的机制,所以 Redis 事务的执行并不是原子性的。事务可以理解为一个打包的批量执行脚本,但批量指令并非原子化的操作,中间某条指令的失败不会原创 2022-12-06 14:55:27 · 694 阅读 · 0 评论 -
Nginx动静分离、缓存配置、性能调优、集群配置
1个web程序:部署在7061端口,启动 【dotnet NginxWeb.dll --urls="http://*:7061" --ip="127.0.0.1" --port=7061】Nginx程序:监听7000端口 比如单独启动部署在7061端口下的web程序,进行访问,我们会发现,除了请求的加载,还有很多静态 css、js、图片等资源的加载,这些资源的加载也是占服务器带宽的,假设带宽为1m,几个大图片直接就占满了。所以这里引入动静分离,将静态资源单独隔离出来,不占据主服务器的带宽,同时也有利于静态原创 2022-12-03 14:53:41 · 858 阅读 · 0 评论 -
Redis之String类型和Hash类型的介绍和案例应用
典型的Key-Value集合,如果要存实体,需要序列化成字符串,获取的时候需要反序列化一下。原创 2022-12-02 14:50:02 · 672 阅读 · 0 评论 -
MySQL索引底层数据结构原理剖析
我们平时所说的:聚集索引(主键索引),次要索引,覆盖索引,复合索引,前缀索引,唯一索引在MySQL5.7和 8.0版本默认都是使用索引,除此之外还有。至于MySQL5.7之前版本,这里就不过多探究了。原创 2022-12-01 15:25:56 · 227 阅读 · 0 评论 -
深究用户模式锁的使用场景(异变结构、互锁、旋转锁)
本章节,将结合多线程来介绍锁机制, 那么问题来了,什么是锁呢?为什么需要锁?为什么要结合多线程来介绍锁呢?锁的使用场景又是什么呢?DotNet中又有哪些锁呢?在接下来的几个章节中,将陆续解答这些问题。PS:多个线程对一个共享资源进行使用的时候,会出问题, 比如实际的业务场景,入库和出库操作同时进行,库存量就会存在并发问题。所以锁就是用来解决多线程资源竞用的问题。原创 2022-11-30 15:13:18 · 152 阅读 · 0 评论 -
从多个角度分析顺序表和链表区别和特点
顺序表和链表由于存储结构上的差异,导致他们有不同的特点,从而适用于不同的场景。虽然他们都属于线性表,但他们的存储结构有着本质的不同:1. 线性表存储数据,需要,然后将数据按照次序逐一存储,数据之间紧密贴合,不留一丝空隙, 如下图:2. 链表的存储方式与顺序表截然相反,原创 2022-11-29 14:55:33 · 198 阅读 · 0 评论 -
链表剖析及自己手撸“单链表“实现基本操作(初始化、增、删、改等)
存储数据元素时,除了存储数据元素本身的信息外,还有一个指针,指向他的后继节点,最后一个元素的指针不指向任何元素。:在单链表的基础上加一个前驱指针,指向前一个元素,是链表可以双向查找,这种结构成为双链表。:将链表最后一个节点的指针指向第一个节点,这样就形成了一个环,这种数据结构叫做单向循环列表.另外还有双向循环列表.原创 2022-11-28 16:36:13 · 188 阅读 · 0 评论 -
linux常用服务配置、网络配置 和 基于FTP的上传和下载的几种方式
hostname: 查看主机名hostname xxx: 修改主机名(重启后无效)原创 2022-11-26 14:43:15 · 176 阅读 · 0 评论 -
ThreadPool的线程开启、线程等待、线程池的设置、定时功能
ThreadPool简介:ThreadPool是一个线程池,当你需要开启n个线程时候,只需把这个指令抛给线程池,它将自动分配线程进行处理,它诞生于.Net 2.0时代。ThreadPool与Thread的区别:①:Thread每开启一个异步任务,就需要使用一个Thread,具有专一性,即使Thread已经死掉,仍然需要占用资源。②:ThreadPool能实现n个线程处理n+m个异步任务,且没有死线程,默认都是初始化的。原创 2022-11-25 14:03:41 · 416 阅读 · 0 评论 -
MySQL的存储引擎及常用数据类型介绍
MySQL中的数据用各种不同的技术存储在文件(或者内存)中。这些技术中的每一种技术都使用不同的存储机制、索引技巧、锁定水平并且最终提供不同的功能和能力。通过选择不同的技术,你能够获得额外的速度或者功能,从而改善你的应用的整体功能。。。InnoDB 存储引擎提供了具有提交、回滚和崩溃恢复能力的事务安全。但,且会占用更多的磁盘空间以保留数据和索引。原创 2022-11-23 15:25:06 · 142 阅读 · 0 评论 -
栈简介、手撸顺序栈、手撸链栈和栈的应用
栈是一种只能从表的一端存取数据且遵循 "先进后出"("后进先出") 原则的线性存储结构。栈也是用来存储逻辑关系为 "一对一" 数据的线性存储结构。C#中提供顺序栈:Stack,它不是线程安全的;分析:(1). 栈只能从表的一端存取数据,另一端是封闭的(2). 在栈中,无论是存数据还是取数据,都必须遵循"先进后出"的原则,即最先进栈的元素最后出栈。原创 2022-11-22 15:25:07 · 223 阅读 · 0 评论 -
Redis分布式锁剖析和客户端的实现
在传统的单体项目中,即部署到单个IIS上,针对并发问题,比如进销存中的出库和入库问题,多个人同时操作,属于一个IIS进程中多个线程并发操作的问题,这个时候可以引入线程锁lock/Monitor等,轻松解决这类问题。但是随着业务量的逐渐增大,比如"秒杀业务", 肯定是集群部署,这个时候线程锁已经没用了, 必须引入分布式锁。 常见的分布式锁有:数据库、zookeeper、redis. 本节重点介绍redis的分布式锁.如下图: (1).在分布式系统环境下,一个锁在同一时间只能被一个服务器获取;(这是所有分布式原创 2022-11-19 15:01:12 · 157 阅读 · 0 评论 -
Linux之用户管理、权限管理、程序安装卸载
Ubuntu 推荐使用 apt 进行下载、安装。会从 ubuntu 官网下载(中国区镜像),如果下载速度慢的话,可以设置从其他镜像下载,具体搜索“Ubuntu apt-get 镜像”,执行某些程序的时候,如果程序没安装,还会提示你,比如执行 vim、tree 等。(2). 指定目录和组名:【sudo useradd -d /home/a a -g mygroup1 -m】,创建一个用户名字叫a,主目录在/home/a,如果主目录不存在,就自动创建主目录,同时用户属于mygroup1组。原创 2022-11-18 16:03:35 · 254 阅读 · 0 评论 -
深究并行编程Parallel类中的三大方法 (For、ForEach、Invoke)和几大编程模型(SPM、APM、EAP、TAP)
我们发现一个现象,主线程等着这五个子线程执行完毕后才执行,但是我们并没有写线程等待的代码,所以我们可以总结: ①:并行计算,开启多个线程后,不需要再开辟线程等待,直接是主线程完成后续操作。这里也是介绍一个简单的重载:int数组中的个数代表需要进行并行任务的个数,但并不一定所有任务同时执行,也不一定每个任务都是一个新线程执行。我们发现,五个任务中的四个任务同时由不同线程开启,当其中一个任务结束时,第五个任务开启,并由刚结束的任务的线程来执行。①. 串行编程:所谓的串行编程就是单线程的作用下,按顺序执行。原创 2022-11-17 15:26:02 · 307 阅读 · 0 评论 -
探究并发和并行、同步和异步、进程和线程、阻塞和非阻塞、响应和吞吐等
操作系统扫盲:1. 对于单核cpu而言(不管单核单线程也好,单核多线程也罢),同一时间只能干一件事!!为了看起像可以“同时干多件事”,windows操作系统把cpu的时间划分为长短基本相同的时间区间,即“时间片”,通过操作系统的管理,把这些时间片依次轮流分配给各个应用使用。2. 操作系统时间片的使用规则:某个作业在cpu分配给它的时间片结束时,整个任务并没完成,那么该作业只能被暂停下来,等待下一轮循环再继续做。原创 2022-11-16 15:00:22 · 174 阅读 · 0 评论 -
Redis新特性、剖析线程模型(单线程与多线程)
非阻塞 IO 在 Socket 对象上提供了一个选项Non_Blocking ,当这个选项打开时,读写方法不会阻塞,而是能读多少读多少,能写多少写多少。能读多少取决于内核为 Socket 分配的读缓冲区的大小,能写多少取决于内核为 Socket 分配的写缓冲区的剩余空间大小。读方法和写方法都会通过返回值来告知程序实际读写了多少字节数据。有了非阻塞 IO 意味着线程在读写 IO 时可以不必再阻塞了,读写可以瞬间完成然后线程可以继续干别的事了。补充阻塞IO概念:原创 2022-11-15 15:34:48 · 204 阅读 · 0 评论 -
程序员内功-设计模式篇
(1). 单例(Singleton)模式:某个类只能生成一个实例,该类提供了一个全局访问点供外部获取该实例(不能new创建对象),其拓展是有限多例模式。(2). 原型(Prototype)模式:将一个对象作为原型,通过对其进行复制而克隆出多个和原对象相同或类似的新实例。(3). 工厂方法(Factory Method)模式:定义一个用于创建产品的接口,由子类决定生产什么产品。(4). 抽象工厂(AbstractFactory)模式:提供一个创建产品族的接口,其每个子类可以生产一系列相关的产品。原创 2022-11-12 15:12:49 · 129 阅读 · 0 评论 -
MySQL锁、事务隔离级别、MVCC机制详解、间隙锁、死锁等
脏读是指一个事务读取到了其他事务没有提交的数据,不可重复读是指一个事务内多次根据同一个查询条件查询出来的“同一行记录的值不一样”,幻读是指一个事务内多次 根据同个条件查出来的记录行数不一样。为了解决事务并发带来的问题,才有了事务规范中的四个事务隔离级别,不同隔离级别对上面问题部分或者全部做了避免。MyISAM在执行查询语句(SELECT)前,会自动给涉及的所有表加读锁,在执行增删改操作前,会自动给涉及的表加写锁。原创 2022-11-11 15:31:47 · 136 阅读 · 0 评论 -
探究多线程和异步
在刚接触开发的头几年里,说实话,根本不考虑多线程的这个问题,貌似那时候脑子里也有没有多线程的这个概念,所有的业务都是一个线程来处理,不考虑性能问题,当然也没有考虑多线程操作一条记录存在的并发问题,后面随着处理的系统业务越来越复杂,多线程再也回避不了了,也就借此机会深入研究了一下.Net中的多线程的处理方案。原创 2022-11-10 16:58:38 · 137 阅读 · 0 评论 -
内存数据库如何发挥内存优势?
内存数据库的计算体系,必须充分利用内存的特征才能获得极致性能。从数据计算的角度来看,内存主要优点有:支持指针引用、支持高速随机访问、并发读取能力强。内存的缺点是:成本高昂、扩容有上限。而 SQL 计算体系中缺乏一些必要的数据类型和运算,比如:缺少记录指针类型,不支持有序运算,JOIN 定义过于笼统,不区分 JOIN 类型等,从原理上就不能充分利用内存的上述特征实现某些高速算法。基于 SQL 的内存数据库,通常只是简单的照搬外存数据结构和运算,会出现各种问题。比如:记录式复制过多消耗 CPU 和内存;原创 2022-11-09 15:51:57 · 170 阅读 · 0 评论 -
深入理解Makefile
前面我们声明的BUILDDIR就是一个自定义变量,要注意的是,如果声明了一个和默认变量一样的变量就会覆盖默认变量,这也给我们提供了一个改变默认规则的入口。= 延迟赋值,在Makefile运行时才会被赋值:= 立即赋值,立即赋值是在真正运行前就会被赋值?= 空赋值,如果变量没有设置过才会被赋值+= 追加赋值,可以理解为字符串的加操作延迟赋值指的是在Makefile运行时再赋值。原创 2022-11-08 13:25:25 · 175 阅读 · 0 评论 -
并发编程中的锁、条件变量和信号量
并发是指多个事情,在同一时间段内同时发生了。和并发经常一起被提到的是并行。并行是指多个事情,在同一时间点上同时发生了。本质上来说,并发是为了程序运行的速度更快。在实际开发中,我们可能会遇到比较耗时的操作,例如I/O操作。在整个程序运行过程中,如果某个阶段因为一直等待I/O而阻塞整个程序,就会降低程序的运行速度。为了提升程序的运行速度,我们可以新开一个线程进行I/O操作,操作完成后通知主线程,从而提升程序的运行速度。锁本质上是一个变量,因此我们需要声明一个某种类型的锁变量才能使用。原创 2022-11-04 14:45:33 · 486 阅读 · 0 评论