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

【网络编程】同步和异步、阻塞和非阻塞,I/O和网络I/O

十、基于I/O模型的网络开发

10.1 同步和异步

对于多个线程而言,同步、异步就是线程间的步调是否要一致、是否要协调:要协调线程 之间的执行时机就是线程同步,否则就是异步。

对于一个线程的请求调用来讲,同步和异步的区别是是否要等这个请求出最终结果(注意, 不是请求的响应,是提交的请求最终得到的结果)。如果要等最终结果,就是同步;如果不等, 干其他无关事情了,就是异步。

10.1.1 同步

根据汉语大辞典,同步(Synchronization)是指两个或两个以上随时间变化的量在变化过 程中保持一定的相对关系,或者说,对在一个系统中所发生的事件(event) 之间进行协调, 在时间上出现一致性与统一化的现象。比如说,两个线程要同步,即它们的步调要一致,要相互协调来完成一个或几个事件。

同步也经常用在一个线程内先后两个函数的调用上,后面一个函数需要前面一个函数的结 果,那么前面一个函数就必须完成且有结果才能执行后面的函数。这两个函数之间的调用关系 就是一种同步(调用)。同步调用一旦开始,调用者就必须等到调用方法返回且结果出来(注 意一定要在返回的同时出结果,不出结果就返回那是异步调用)后才能继续后续的行为。同步 一词用在这里也是恰当的,相当于就是一个调用者对两件事情(比如两次方法调用)之间进行 协调(必须做完一件再做另外一件),在时间上保持一致性(先后关系)。

这么看来,计算机中的“同步”一词所使用的场合符合了汉典中的同步含义。

对于线程间而言,要想实现同步操作,就必须获得线程的对象锁。获得它可以保证在同一 时刻只有一个线程能够进入临界区,并且在这个锁被释放之前,其他的线程都不能再进入这个 临界区。如果其他线程想要获得这个对象的锁,只能进入等待队列等待。只有当拥有该对象锁 的线程退出临界区时锁才会被释放,等待队列中优先级最高的线程才能获得该锁。

同步调用相对简单些,比较某个耗时的大数运算函数及其后面的代码就可以组成一个同步调用,相应的,这个大数运算函数也可以称为同步函数,因为必须执行完这个函数才能执行后 面的代码。比如:

long long num = bigNum();
printf("%d",num);

可以说,bigNum 是同步函数,它返回时大数结果就出来了,然后执行后面的printf 函数。

10.1.2 异步

异步就是一个请求返回时一定不知道结果(如果返回时知道结果就是同步了),还得通过 其他机制来获知结果,如主动轮询或被动通知。同步和异步的区别就在于是否等待请求执行的 结果。这里请求可以指一个I/O 请求或一个函数调用等。

为了加深理解,我们举个生活中的例子。比如你去肯德基点餐,你说“来份薯条”,服务 员告诉你,“对不起,薯条要现做,需要等5分钟”,于是你站在收银台前面等了5分钟,拿 到薯条再去逛商场,这是同步。你对服务员说的“来份薯条”就是一个请求,薯条好了就是请 求的结果出来了。

再看异步,你说“来份薯条”,服务员告诉你,“薯条需要等5分钟,你可以先去逛商场, 不必在这里等,薯条做好了,你再来拿”。这样你可以立刻去干别的事情(比如逛商场),这 就是异步。“来份薯条”是一个请求,服务员告诉你的话就是请求返回了,但请求的真正结果 (拿到薯条)没有立即实现。异步一个重要的好处是不必在那里等,而同步肯定是要等的。

很明显,使用异步方式来编写程序性能和友好度会远远高于同步方式,但是异步方式的缺 点是编程模型复杂。

想想看,在上面的场景中,要想吃到薯条,你得知道“什么时候薯条好了”, 有两种方式:一种是你主动每隔一小段时间就跑到柜台上去看薯条有没有好(定时主动关注状 态),这种方式通常称为主动轮询;另一种是服务员通过电话、微信通知你,这种方式称为通 知(被动)。显然,第二种方式更高效。因此,异步还可以分为两种:带通知的异步和不带通 知的异步。

在上面的场景中,“你”可以比作一个线程。

10.2 阻塞和非阻塞

阻塞和非阻塞这两个概念与程序(线程)请求的事情出最终结果前(无所谓同步或者异步) 的状态有关。也就是说阻塞与非阻塞主要是从程序(线程)请求的事情出最终结果前的状态角度来说的。

10.2.1 阻塞

大家学操作系统课程的时候一定知道,线程从创建、运行到结束总是处于下面五个状态之一:新建状态、就绪状态、运行状态、阻塞状态及死亡状态。

阻塞状态的线程特点是:

该线程放弃CPU 的使用,暂停运行,只有等到导致阻塞的原因消除之后才恢复运行。或者是 被其他的线程中断,该线程也会退出阻塞状态,同时抛出InterruptedException。线程运行过程 中,可能由于各种原因进入阻塞状态:

  • (1)线程通过调用sleep 方法进入睡眠状态。
  • (2)线程调用一个在I/O 上被阻塞的操作,即该操作在输入输出操作完成之前不会返回 到它的调用者。
  • (3)线程试图得到一个锁,而该锁正被其他线程持有。于是只能进入阻塞状态,等到获 取了同步锁,才能恢复执行
  • (4)线程在等待某个触发条件。
  • (5)线程执行了一个对象的wait()方法,直接进入阻塞状态,等待其他线程执行notify( 或者notifyAll()方法。

这里我们要关注一下第(2)条,很多网络I/O 操作都会引起线程阻塞,比如 recv 函数, 但数据还没有过来或还没有接收完毕,线程就只能阻塞等待这个I/O 操作完成。这些能引起线 程阻塞的函数通常称为阻塞函数。

阻塞函数其实就是一个同步调用,因为要等阻塞函数返回才能继续执行其后的代码。有阻 塞函数参与的同步调用一定会引起线程阻塞,但同步调用并不一定会阻塞,比如同步调用关系 中没有阻塞函数或引起其他阻塞的原因存在。举个例子,一个非常消耗CPU 时间的大数运算 函数及其后面的代码,这个执行过程也是一个同步调用,但会引起线程阻塞。

这里,我们可以区分一下阻塞函数和同步函数。同步函数被调用时不会立即返回,直到该函数所要做的事情全都做完了才返回。阻塞函数也是被调用时不会立即返回,直到该函数所要做的事情全都做完了才返回,而且会引起线程阻塞。这么看来,阻塞函数一定是同步函数,但同步函数不仅指阻塞函数。

强调一下,阻塞一定是引起线程进入阻塞状态的。

这里给出一个生活场景来加深理解:小明去买薯条,服务员告诉他5分钟后才能好,小明 说“好吧,我在这里等”,同时他睡了一会。这就是阻塞,而且是同步阻塞,在等并且睡着了。

10.2.2 非阻塞

非阻塞是指在不能立刻得到结果之前请求不会阻塞当前线程,而会立刻返回(比如返回一 个错误码)。虽然表面上看非阻塞的方式可以明显地提高CPU 的利用率,但是也带来另外一 种后果,就是系统的线程切换增加。增加的CPU 执行时间能不能补偿系统的切换成本需要好 好评估。
强调一下,非阻塞不会引起线程进入阻塞状态,而且请求是马上有响应的(比如返回一个 错误码)。

10.3 同步/异步和阻塞/非阻塞的关系

给一个生活场景来加深理解:你去买薯条,服务员告诉你5分钟后才能好,那你就站在柜 台旁开始等,但人没有睡过去,或许还在玩微信。这就是非阻塞,而且是同步非阻塞,在等但 没有睡过去,还可以玩玩手机。
如果你没有等,只是告诉服务员薯条好了后告诉我或者我过段时间来看看状态(好了没有),然后不等就跑去逛街了。这属于异步非阻塞。事实上,异步肯定是非阻塞的,因为异步 肯定要做其他事情了,做其他事情是不可能睡过去的,所以异步只能是非阻塞的。

注意,同步非阻塞形式实际上是效率低下的。想象一下你一边玩手机一边还需要时刻留意 着到底薯条有没有好,大脑频繁来回切换关注,很累,手机游戏也玩不好。如果把玩手机和观 察薯条状态看成是程序的两个操作,那么这个程序需要在两种不同的行为之间来回切换,效率 肯定是低下的;异步非阻塞形式则没有这样的问题,因为你不必再等薯条是否好了(以后会有人通知或过一段时间去主动看一下有没有好),可以尽情地去逛街或在其他安静的地方玩手机。 程序没有在两种不同的操作中来回频繁切换。

同步非阻塞虽然效率不高,但比同步阻塞高很多,同步阻塞除了傻等,其他任何事情都做 不了,因为“睡过去”了。

10.4 I/O 和 网 络I/O

I/O(Input/Output, 输入/输出)即数据的读取(接收)或写入(发送)操作,通常用户进 程中的一个完整IO 分为两阶段:用户进程空间 → 内核空间、内核空间 →设备空间(磁盘、网 络 等 ) 。IO 分内存IO、网 络IO 和磁盘IO 三种,本章我们讲的是网络IO。

Windows 中进程无法直接操作I/O 设备,必须通过系统调用请求内核来协助完成I/O 动作。 内核会为每个I/O 设备维护一个缓冲区。对于一个输入操作来说,进程IO 系统调用后,内核 会先看缓冲区中有没有相应的缓存数据,没有的话再到设备(比如网卡设备)中读取,因为设 备IO 一般速度较慢,需要等待;内核缓冲区有数据就直接复制到用户进程空间。所以, 一个 网络输入操作通常包括两个不同的阶段:

  • (1)等待网络数据到达网卡,把数据从网卡读取到内核缓冲区,数据准备好。
  • (2)从内核缓冲区复制数据到用户进程空间。

10.5 I/O模式

在 Windows 下,套接字有两种I/O(Input/Output, 输入输出)模式:阻塞模式(也称同 步模式)和非阻塞模式(也称异步模式)。默认创建的套接字属于阻塞模式的套接字。

10.5.1 阻塞模式

在阻塞模式下,在I/O 操作完成前,执行的操作函数一直等候而不会立即返回,该函数所 在的线程会阻塞在这里(线程进入阻塞状态)。相反,在非阻塞模式下,套接字函数会立即返 回,而不管I/O 是否完成,该函数所在的线程会继续运行。

在阻塞模式的套接字上,调用大多数Windows Sockets API函数都会引起线程阻塞,但并 不是所有Windows Sockets API以阻塞套接字为参数调用都会发生阻塞。例如,以阻塞模式的 套接字为参数调用bind() 、listen(函数时,函数会立即返回。

这里将可能阻塞套接字的Windows Sockets API调用分为以下4种。

  • (1)输入操作:包括 recv() 、recvfrom() 、WSARecv() 和 WSARecvfrom()函数。以阻塞套接字为参数调用 该函数接收数据。如果此时套接字缓冲区内没有数据可读,那么调用线程在数据到来前一直阻塞。
  • (2)输出操作:包括 send() 、sendto() 、WSASend ( 和WSASendto() 函数。以阻塞套接字为参数调用该函数 发送数据。如果套接字缓冲区没有可用空间,线程就会一直睡眠,直到有空间。
  • (3)接受连接:包括 accept() 和WSAAcept() 函数。以阻塞套接字为参数调用该函数,等待接受对方的连接 请求。如果此时没有连接请求,线程就会进入阻塞状态。
  • (4)外出连接:包括 connect()和WSAConnect()函数。对于TCP 连接,客户端以阻塞套接字为参数,调用 该函数向服务器发起连接。该函数在收到服务器的应答前不会返回。这意味着TCP 连接总会 等待至少到服务器的一次往返时间。
    使用阻塞模式的套接字,开发网络程序比较简单,容易实现。当希望能够立即发送和接收 数据且处理套接字数量比较少的情况下,使用阻塞模式来开发网络程序比较合适。

阻塞模式套接字的不足表现为,在大量建立好的套接字线程之间进行通信时比较困难。

当 使用“生产者-消费者”模型开发网络程序时,为每个套接字分别分配一个读线程、 一个处理数据线程和一个用于同步的事件,这样无疑会加大系统的开销。其最大的缺点是当希望同时处理大量套接字时将无从下手,可扩展性很差。

总之,我们要时刻记住阻塞函数和非阻塞函数的重要区别:阻塞函数,通常指一旦调用了,线程就阻塞;非阻塞函数一旦调用,线程并不会挂,而是会返回一个错误码,表示结果还没有出来

10.5.2 非阻塞模式

而对于处于非阻塞模式的套接字,会马上返回而不去等待该I/O 操作完成。针对不同的模 式 ,Winsock 提供的函数也有阻塞函数和非阻塞函数。相对而言,阻塞模式比较容易实现,在 阻塞模式下,执行I/O 的 Winsock 调 用 ( 如send 和 recv) 一直到操作完成才返回。

10.6 I/O 模型

为什么要采用Socket I/O模型,而不直接使用Socket? 原因在于recv()方法是堵塞式的, 当多个客户端连接服务器时,其中一个socket 的 recv 调用时会产生堵塞,使其他链接不能继续。

这样我们又想到用多线程来实现,每个 socket 链接使用一个线程,这样效率十分低下, 根本不可能应对负荷较大的情况。于是便有了各种模型的解决方法,总之都是为了实现多个线程同时访问时不产生堵塞。

如果使用“同步”的方式(所有的操作都在一个线程内顺序执行完成)来通信,那么缺点 是很明显的:因为同步的通信操作会阻塞来自同一个线程的任何其他操作,只有这个操作完成 了之后,后续的操作才可以完成;

一个明显的例子就是在 MFC 的界面代码中直接使用阻塞 Socket调用代码,整个界面都会因此而阻塞,没有任何响应! 所以我们不得不为每一个通信的 Socket 都建立一个线程,很麻烦,所以要写高性能的服务器程序,要求通信一定是异步的。

各位读者肯定知道,可以使用“同步通信(阻塞通信)+多线程”的方式来改善同步阻塞 线程的情况。

想一下,我们好不容易实现了让服务器端在每一个客户端连入之后都启动一个新 的 Thread 和客户端进行通信,有多少个客户端,就需要启动多少个线程;但是这些线程都处 于运行状态,所以系统不得不在所有可运行的线程之间进行上下文切换。我们自己没有什么感 觉,但是CPU 就痛苦不堪了,因为线程切换是相当浪费CPU 时间的,如果客户端的连入线程 过多,就会弄得CPU 都忙着去切换线程了,根本没有多少时间去执行线程体,所以效率是非 常低下的。

在阻塞I/O 模式下,如果暂时不能接收数据,那么接收函数(比如recv/WSARecv) 不 会 立即返回,而是等到有数据可以接收时才返回;如果一直没有数据,该函数就会一直等待下去, 应用程序也就挂起了。

很显然,异步的接收方式更好一些,因为无法保证每次的接收调用总能 适时地接收到数据。而异步的接收方式也有其复杂之处,比如立即返回的结果并不总是成功收发数据,实际上很可能会失败,最多的失败原因是WSAEWOULDBLOCK 。 可 以 使 用 WSAGetLastError 函数得到发送和接收失败时的失败原因。这个失败原因较为特殊,也常出现, 它的意思是说要进行的操作暂时不能完成,如果在以后的某个时间再次执行该操作也许就会是成功的。如果发送缓冲区已满,这时调用 WSASend 函数就会出现这个错误。同理,如果接收缓冲区内没有内容,这时调用 WSARecv 也会得到同样的错误。这并不意味着发送和接收调 用会永远失败下去,而是在以后某个适当的时间,比如发送缓冲区有空间了、接收缓冲区有数 据了,再调用发送和接收操作就会成功了。那么什么时间是恰当的呢?这就是套接字10模型 产生的原因了,它的作用就是通知应用程序发送或接收数据的时间点到了,可以开始收发了。

在非阻塞模式下,Winsock 函数会立即返回。阻塞套接字的好处是使用简单,但是当需要处理多个套接字连接时,就必须创建多个线程,即典型的一个连接使用一个线程的问题,这给编程带来了许多不便。所以实际开发中使用最多的还是下面要讲述的非阻塞模式。

非阻塞模式比较复杂,为了实现套接字的非阻塞模式,微软提出了非阻碍套接字的5种I/O 模型:

  • (1)选择模型,或称Select 模型,主要是利用Select 函数实现对I/O 的管理。
  • (2)异步选择模型,或称WSAAsyncSelect 模型,允许应用程序以Windows 消息的方式 接收网络事件通知。
  • (3)事件选择模型,也称WSAEventSelect 模型,类似于WSAAsynSelect 模型,两者最 主要的区别是在事件选择模型下网络事件发生时会被发送到一个事件对象句柄,而不是发送到 一个窗口。
  • (4)重叠I/O 模型,可以要求操作系统传送数据,并且在传送完毕时通知。具体实现时, 可以使用事件通知或者完成例程两种方式分别实现重叠I/O 模型。重叠I/O(Overlapped I/O)模型比上述3种模型能达到更佳的系统性能。
  • (5)完成端口模型,是最为复杂的一种I/O 模型,当然性能也是最强大的。当一个应用 程序同时需要管理很多个套接字时,可以采用这种模型,往往可以达到最佳的系统性能。

不同的模型,程序架构是不同的,相对而言,难度依次递增。强调一下,这5种模型都是 针对非阻塞模式。

参考书籍:《Visual C++ 2017网络编程实战》

相关文章:

【网络编程】同步和异步、阻塞和非阻塞,I/O和网络I/O

十、基于I/O模型的网络开发 10.1 同步和异步 对于多个线程而言,同步、异步就是线程间的步调是否要一致、是否要协调:要协调线程 之间的执行时机就是线程同步,否则就是异步。 对于一个线程的请求调用来讲,同步和异步的区别是是否…...

第本章:go 切片

注意: 切片必须要初始化 才能使用 ,切片是引用类型 a :[]int{} // 这上叫始化 此时并没有申请内存 // 如果要追加值的话: append ints : append(a, 1, 2, 3)a : make([]int,5) // 声明切片类型var a []string //声明一…...

VsCode导入时选择相对路径

自动导入时总是以db://开头了,而我们通常需要的是相对路径,对VsCode进行如下设置: 打开 VSCode 设置: 使用快捷键 Ctrl ,(Windows/Linux)或 Cmd ,(Mac)。 或者在菜单栏中选择 …...

CarPlanner:用于自动驾驶大规模强化学习的一致性自回归轨迹规划

25年2月来自浙大和菜鸟网络的论文“CarPlanner: Consistent Auto-regressive Trajectory Planning for Large-scale Reinforcement Learning in Autonomous Driving”。 轨迹规划对于自动驾驶至关重要,可确保在复杂环境中安全高效地导航。虽然最近基于学习的方法&a…...

Vue3:本地启动Vue3项目失败,报not found xxx moudel

一、情况描述 我这边是从git上下载的一份可用代码 是之前在公司上传的 于是,在加clone到本地。继续开发 get到项目后,我先进行了:npm install,也没显示报错。 启动的时候报错。 二、解决 rm -rf node_modules npm cache clean…...

nodejs去除本地文件html字符

说明:我希望用nodejs 写一个小工具,去除本地txt文件中的html字符,去除字符后生成新的文件,同样保存在桌面 文件的具体位置是C:\Users\Administrator\Desktop\file.txt step1:C:\Users\Administrator\WebstormProjects\untitled4\f…...

dify部署

https://github.com/langgenius/dify 介绍 Dify 是一款开源的大语言模型(LLM) 应用开发平台。它融合了后端即服务(Backend as Service)和 LLMOps 的理念,使开发者可以快速搭建生产级的生成式 AI 应用。Dify 内置了构建 LLM 应用所需的关键技…...

【Redis】常用命令汇总

Redis 作为高性能的键值存储数据库,提供了丰富的命令集,主要涵盖 字符串 (String)、哈希 (Hash)、列表 (List)、集合 (Set)、有序集合 (ZSet)、键 (Keys)、Geo(地理位置)、HyperLogLog(基数统计)、Bitmap&a…...

分析TCP三次握手与四次挥手

TCP(传输控制协议)通过三次握手建立连接,四次挥手终止连接,确保数据传输的可靠性。 TCP的三个控制标志位: SYN——用于建立连接,同步序列号。 ACK——用于确认收到的数据。 FIN——用于终止连接。 ISN…...

C++之序列容器(vector,list,dueqe)

1.大体对比 在软件开发的漫长历程中,数据结构与算法始终占据着核心地位,犹如大厦的基石,稳固支撑着整个程序的运行。在众多编程语言中,数据的存储与管理方式各有千秋,而 C 凭借其丰富且强大的工具集脱颖而出&#xff…...

网络安全技术和协议(高软43)

系列文章目录 网络安全技术和协议 文章目录 系列文章目录前言一、网络安全技术1.防火墙2.入侵检测系统IDS3.入侵防御系统IPS 二、网络攻击和威胁三、网络安全协议四、真题在这里插入图片描述 总结 前言 本节讲明网络安全技术和协议方面的相关知识。 一、网络安全技术 1.防火…...

LeetCode697

好的,根据你提供的代码和LeetCode题号(697),我将帮助你生成一个结构化的Markdown文档。首先,我们需要补充一些必要的信息,如题目描述、示例、思路分析等。如果你能提供这些信息会更好,否则我会基…...

js基本功(四)

ASCII ASCII(American Standard Code for Information Interchange,美国信息交换标准代码)是一种字符编码标准,用于表示英文字符、数字、标点符号以及一些控制字符。 可以通过 charCodeAt() 方法获取字符的 ASCII 码,也可以通过 String.fromCharCode() 方法将 ASCII 码转…...

linux | Vim 命令快捷操作

注:本文为过去的 “vim 使用笔记”。 跳转命令 跳转命令 #:向前查找光标当前所在单词,并跳转到该单词的上一个出现位置。*:向后查找光标当前所在单词,并跳转到该单词的下一个出现位置。 行内跳转 0:跳转…...

开源订货系统哪个好 三大订货系统源码推荐

在数字化转型加速的今天,企业对订货系统的需求日益增长。一款优质的订货系统源码不仅能提升供应链效率,还能通过二次开发满足个性化业务需求。这里结合 “标准化、易扩展” 两大核心要求,为您精选三款主流订货系统源码,助您快速搭…...

跟着 Lua 5.1 官方参考文档学习 Lua (11)

文章目录 5.4.1 – PatternsCharacter Class:Pattern Item:Pattern:Captures: string.find (s, pattern [, init [, plain]])例子:string.find 的简单使用 string.match (s, pattern [, init])string.gmatch (s, pattern)string.gsub (s, pattern, repl [, n])例子&…...

使用 MyBatis XML 和 QueryWrapper 实现动态查询

本文档介绍了如何在 MyBatis 中结合 XML 配置和 MyBatis-Plus 的 QueryWrapper 来实现动态查询。 1. XML 中定义基本查询 首先&#xff0c;在 MyBatis XML 文件中定义一个基本的 select 查询&#xff1a; <select id"selectCode" resultType"java.util.Ma…...

视频理解开山之作 “双流网络”

1 论文核心信息 1.1核心问题 任务&#xff1a;如何利用深度学习方法进行视频中的动作识别&#xff08;Action Recognition&#xff09;。挑战&#xff1a; 视频包含时空信息&#xff0c;既需要捕捉静态外观特征&#xff08;Spatial Information&#xff09;&#xff0c;也需要…...

每日一题——搜索二维矩阵

搜索二维矩阵 一、题目背景二、题目描述示例 1&#xff1a;示例 2&#xff1a;约束条件&#xff1a; 三、解题思路分析1. **错误思路回顾**2. **Z字形查找算法**算法步骤&#xff1a; 3. **算法优势** 四、代码实现代码说明&#xff1a; 五、测试用例测试用例 1&#xff1a;测试…...

PPT 小黑第21套

对应大猫22 动作按钮 “转到首页” 编号从1开始显示&#xff0c;点设计 -幻灯片大小 -修改幻灯片编号起始值为0&#xff08;那么第二张幻灯片页码为1&#xff09;...

大模型day01自然语言+大模型+环境

[TOC]大模型day01 自然语言处理 汉字的词是连着的&#xff0c;所以需要一个汉语处理模块&#xff0c;把词语、成语自动加空格隔开。 知识图谱构建——>从大语言文本挖掘出来 自然语言处理&#xff1a;翻译、智能语音 自然语言处理&#xff1a;理解一句话意思&#xff0c…...

VSTO(C#)Excel开发3:Range对象 处理列宽和行高

初级代码游戏的专栏介绍与文章目录-CSDN博客 我的github&#xff1a;codetoys&#xff0c;所有代码都将会位于ctfc库中。已经放入库中我会指出在库中的位置。 这些代码大部分以Linux为目标但部分代码是纯C的&#xff0c;可以在任何平台上使用。 源码指引&#xff1a;github源…...

【2025】Electron + React 架构筑基——从零到一的跨平台开发

引言 源代码仓库&#xff1a; Github仓库【electron_git】 你是否厌倦了在命令行中反复输入git status&#xff0c;却依然无法直观看到文件变化&#xff1f; 是否羡慕VS Code的丝滑Git集成&#xff0c;却苦恼于无法定制自己的专属工具&#xff1f; 本专栏将为你打开一扇新的…...

AWS 如何导入内部SSL 证书

SSL 证书的很重要的功能就是 HTTP- > HTTPS, 下面就说明一下怎么导入ssl 证书,然后绑定证书到ALB. 以下示例说明如何使用 AWS Management Console 导入证书。 从以下位置打开 ACM 控制台:https://console.aws.amazon.com/acm/home。如果您是首次使用 ACM,请查找 AWS Cer…...

清华北大推出的 DeepSeek 教程(附 PDF 下载链接)

清华和北大分别都有关于DeepSeek的分享文档&#xff0c;内容非常全面&#xff0c;从原理和具体的应用&#xff0c;大家可以认真看看。 北大 DeepSeek 系列 1&#xff1a;提示词工程和落地场景.pdf  北大 DeepSeek 系列 2&#xff1a;DeepSeek 与 AIGC 应用.pdf  清华 Deep…...

【空地协同技术教程:概念与技术手段解析】

空地协同技术教程&#xff1a;概念与技术手段解析 一、空地协同的概念与核心价值 定义 空地协同&#xff08;Air-Ground Collaboration&#xff09;是指通过无人机&#xff08;UAV&#xff09;与无人车&#xff08;UGV&#xff09;等异构平台的跨域协作&#xff0c;利用各自的…...

【2025小黑课堂】计算机二级WPS精选系列20G内容(可下载:真题+预测卷+软件+选择题)

2025年3月全国计算机等级考试即将于3月29日至31日举行。为了帮助广大考生高效备考&#xff0c;小编特意收集并整理了最新版&#xff08;备考2025年3月&#xff09;的小黑课堂计算机二级WPS 电脑题库软件&#xff0c;助力考生在考试中游刃有余&#xff0c;轻松通关&#xff01; …...

蓝桥杯备赛:炮弹

题目解析 这道题目是一道模拟加调和级数&#xff0c;难的就是调和级数&#xff0c;模拟过程比较简单。 做法 这道题目的难点在于我们在玩这个跳的过程&#xff0c;可能出现来回跳的情况&#xff0c;那么为了解决这种情况&#xff0c;我们采取的方法是设定其的上限步数。那么…...

kotlin高级用法总结

Kotlin 是一门功能强大且灵活的编程语言&#xff0c;除了基础语法外&#xff0c;它还提供了许多高级特性&#xff0c;可以帮助你编写更简洁、高效和可维护的代码。以下是 Kotlin 的一些高级用法&#xff0c;涵盖了协程、扩展函数、属性委托、内联类、反射等内容。 协程&#x…...

transformers - AWQ

本文翻译整理自&#xff1a;https://huggingface.co/docs/transformers/main/en/quantization/awq 文章目录 一、引言二、加载 autoawq 量化的模型三、Fused modules支持的架构不受支持的架构 四、ExLlamaV2五、CPU 一、引言 Activation-aware Weight Quantization (AWQ) 激活…...