不知道怎么入门Selet、Poll、Epoll?看这篇文章就够了!

【计算摄影】相机成像原理:从光到JPEG图像 本文我们将从最基本的相机成像原理开始论述,再讨论光线进入相机后,经过一系列处理成为JPEG图像的大致流程。 阅读详情

前置知识:

  1. 用户空间和内核空间
  2. 进程切换
  3. 进程的阻塞
  4. 文件描述符
  5. 缓存 IO
  6. 中断

如果对以上概念还有不清楚的地方的话,可以先手动百科下再继续往下看~

I/O多路复用

首先我们来了解一下文件描述符:在Unix哲学中:“Everything is a file."Socket、pipe都可以看做文件,并且有自己独一无二的文件描述符(缩写为fd),而文件常常面临着读数据和写数据。

然后我们来了解一下I/O的概念:I/O分别是input和output的说写,也就是读数据和写数据,我们通过write可以往文件中写数据,而通过read从文件中读取数据。

那阻塞I/O是什么意思呢?如果在文件描述符中的数据还没有准备好的时候:例如在还没有任何数据的时候,发送了read()调用,进程就会堵塞,

那有没有什么好办法?我们可以同时监听多个fd,在有fd就绪的时候进行通知,没有的时候就堵塞?有,那就是I/O多路复用!

I/O多路复用就像是公司的收发室小哥,会替你处理中通、顺丰、韵达、申通…等等各家快递公司的快递,等哪家的快递到了,再打电话通知你拿~这个时候你就有很多时间在办公室愉快地摸鱼啦!

那在操作系统里,该如何设计这样的收发室小哥呢?

  1. 当有一个fd就绪时进行通知(等待小哥给你发短信)
  2. 都不可用?在有可用的文件描述符之前一直处于堵塞状态(专心在工位摸鱼)
  3. 唤醒:哪个fd可用了?(收到短信,下楼拿快递)
  4. 处理完所有的I/O就绪的fd,没有堵塞(拿完所有的快递,没有摸鱼)
  5. 返回第一步重新开始(上楼,回到工位,继续摸鱼)

UNIX公司里提供了select、poll、epoll、kqueue这几位年纪、性格和能力都有所差异的收发室小哥,让我们分别介绍下这几位小哥的工作特点吧!

select

select是最早出现在UNIX里的多路复用有关的系统调用:

#include<sys/select.h>
int selcet( int n,
            fd_set *readfds,
            fd_set *writefds,
            fd_set *exceptfds,
            struct timeval *timeout
            );

FD_CLR(int fd, fd_set *set);
FD_ISSET(int fd, fd_set *set);
FD_SET(int fd, fd_set *set);
FD_ZERO(fd_set *set);

readfds、writefds、exceptfds分别表示select所监视的不同类型的文件描述符,分别等待不同的事件:监视是否有数据可读、监视是否有数据可写、是否有异常etc。第一个参数n呢,等于所有集合中最大的文件描述符的值加一。当selet成功返回时,readfds、writefds、exceptfds都会写改为只包含对应类型的I/O就绪的文件描述。举个例子,readfds对应的是中通快递,而显示有编号1、2、3的快递在发往我们收发室,在select检查快递的时候,只有2到了,因此readfds集合就只返回编号为2的快递。参数timeout是只想timeval结构体的指针:

#include<sys/time.h>

struct timeval{
    long tv_sec; 
    long tv_usec; 

}

如果该参数不是NULL,在tv_sec秒tv_usec毫秒过后select系统调用就会返回。

FD_ZERO(fd_set *fdset):清空fdset与所有文件描述符的联系。

FD_SET(int fd, fd_set *fdset):建立文件描述符fd与fdset的联系。

FD_CLR(int fd, fd_set *fdset):清除文件描述符fd与fdset的联系。

FD_ISSET(int fd, fd_set *fdset):检查fd_set联系的文件描述符fd是否可读写,>0表示可读写。

typedef __kernel_fd_set     fd_set;
#undef __FD_SETSIZE
#define __FD_SETSIZE    1024

typedef struct {
    unsigned long fds_bits[__FD_SETSIZE / (8 * sizeof(long))];
} __kernel_fd_set;

select()的机制中提供一种fd_set的数据结构,fd_set是一个struct, 其内部只有一个 由16个元素组成的unsigned long数组,其实就是常见的bitmap,这个数组一共可以表示16 × 64 = 1024位, 每一位用来表示一个 fd, 这也就是 select针对读,定或异常每一类最多只能有 1024个fd 限制的由来。当调用select()时,由内核根据IO状态修改fd_set的内容,由此来通知执行了select()的进程哪一Socket或文件可读。

select机制的问题

1.单个进程能够监视的文件描述符的数量存在最大限制,通常是1024,这个大小是由宏控制的,进行改变很麻烦(在linux内核头文件中,有这样的定义:#define __FD_SETSIZE 1024),并且由于select采用轮询的方式扫描文件描述符,文件描述符数量越多,性能越差;

2.内核 / 用户空间内存拷贝问题:select需要复制大量的句柄数据结构,产生巨大的开销;

3.select的触发方式是水平触发,应用程序如果没有完成对一个已经就绪的文件描述符进行IO操作,那么之后每次select调用还是会将这些文件描述符通知进程。

poll

早期淘宝购物并不发达,所以收发室的快件并不是很多,select轮询上限1024个快件的工作方式也够用了。但随着网络购物的发展,收发室的快递越来越多,select模式下fd_set的长度限制就开始成为了致命缺陷。

吸取了select的教训,新引入的poll就不再采用定长数组来保存所监控的fd信息了,而是采用可以改变长度的链表,没有了连接数目的限制,poll可以支持高并发的需求。除此以外,poll本质上和select没有区别,它将用户传入的数组拷贝到内核空间,然后查询每个fd对应的设备状态,如果设备就绪则在设备等待队列中加入一项并继续遍历,如果遍历完所有fd后没有发现就绪设备,则挂起当前进程,直到设备就绪或者主动超时,被唤醒后它又要再次遍历fd。这个过程经历了多次无谓的遍历。

poll用来保存事件的数据结构:

#include <poll.h>

struct pollfd {
    int fd; /* file descriptor */
    short events; /* requested events to watch */
    short revents; /* returned events witnessed */
};

使用poll函数进行操作:

#include <poll.h>

int poll (struct pollfd *fds, unsigned int nfds, int timeout);

fds:一个pollfd队列的队头指针,我们先把需要监视的文件描述符和他们上面的事件放到这个队列中

nfds:队列的长度

timeout:事件操作,设置指定正数的阻塞事件,0表示非阻塞模式,-1表示永久阻塞。

epoll:

设想一个场景,双十一到了,公司总共有一万份快递要来,而实际上每一段时间只会有几十个或者几百个快递到达收发室,也就是说,每一时刻工作人员只需要处理一万份快递中的一小部分快递,那么如何才能高效的处理这种场景呢?如果继续采用select和poll轮询的方法,收发室工作人员一定会累坏吧。实际上,在Linux 2.4版本以前, unix公司就是这么做的。Linux 2.4版中,引入了epoll,它在Linux内核中申请了一个简易的文件系统,把原先的一个select或poll调用分成了3部分,相当于把select和poll的工作分给三个人来做:

#include <sys/epoll.h>
int epoll_create(int size);
int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event);
int epoll_wait(int epfd, struct epoll_event * events, int maxevents, int timeout);
  1. 调用epoll_create建立一个epoll对象(在epoll文件系统中给这个句柄分配资源);

  2. 调用epoll_ctl向epoll对象中添加这100万个连接的套接字;

  3. 调用epoll_wait收集发生事件的连接。

这样只需要在进程启动时建立1个epoll对象,并在需要的时候向它添加或删除连接就可以了,因此,在实际收集事件时,epoll_wait的效率就会非常高,因为调用epoll_wait时并没有向它传递这100万个连接,内核也不需要去遍历全部的连接。

当进程调用epoll_create方法的时候,Linux内核就会创建一个eventpoll结构体,对于这个结构体我们主要需要关注两个成员:

struct eventpoll {
...
  struct rb_root rbr;

  struct list_head rdllist;

...
};

我们在调用epoll_create时,内核除了帮我们在epoll文件系统里建了个file结点,在内核cache里建了个红黑树用于存储以后epoll_ctl传来的socket外,还会再建立一个rdllist双向链表,用于存储准备就绪的事件,当epoll_wait调用时,仅仅观察这个rdllist双向链表里有没有数据即可。有数据就返回,没有数据就sleep,等到timeout时间到后即使链表没数据也返回。所以,epoll_wait非常高效。

所有添加到epoll中的事件都会与设备(如网卡)驱动程序建立回调关系,也就是说相应事件的发生时会调用这里的回调方法。这个回调方法在内核中叫做ep_poll_callback,它会把这样的事件放到上面的rdllist双向链表中。

在epoll中,对于每一个事件都会建立一个epitem结构体:

struct epitem {
  ...
  //红黑树节点
  struct rb_node rbn;
  //双向链表节点
  struct list_head rdllink;
  //事件句柄等信息
  struct epoll_filefd ffd;
  //指向其所属的eventepoll对象
  struct eventpoll *ep;
  //期待的事件类型
  struct epoll_event event;
  ...
}; // 这里包含每一个事件对应着的信息。

因此当我们调用epoll_wait检查是否有就绪的事件时,只是检查eventpoll对象中的rdllist双向链表中是否有epitem, 如果非空的话,就将这里的时间复制到用户态内存中,同时返回时间的数量。因此epoll_wait的效率很高。而epoll_ctl对epoll对象中的事件进行增删查改时,由于使用了红黑树,因此查找事件也是十分高效的。

总结

Linux系统中存在着select、poll、epoll三种系统调用,针对高并发,且任一时间只有少数socket是活跃的场景epoll的性能要好很多。 但是如果在并发量低,socket都比较活跃的情况下,select/poll就不见得比epoll慢了(就像我们常常说快排比插入排序快,但是在特定情况下这并不成立)。并且由于历史原因(先来后到),select因为兼容性比较好,仍然在被大量应用中。

告别调参玄学:用 DINOv2 (ViT-S/ViT-G) 和 PCA 可视化,直观理解自监督特征 本文深入解析了DINOv2(ViT-S/ViT-G)模型在自监督学习中的特征提取机制,通过PCA降维技术实现特征空间的可视化。文章对比了不同规模模型的特征表达差异,并提供了PCA阈值调优和深度分析的实用技巧,帮助读者直观理解自监督学习的视觉密码。 阅读详情

相关推荐

Revit Dynamo实战:用Excel数据批量生成桥梁模型(附自适应族技巧)

本文详细介绍了如何利用Revit Dynamo结合Excel数据实现桥梁参数化建模,重点讲解了数据驱动建模、自适应族优化及大型项目性能管理三大核心技巧。通过结构化Excel数据、高级自适应族创建和分块处理策略,显著提升桥梁建模效率与设计变更响应能力。

weixin_42520025的博客 388

linux驱动系列学习之poll(九)

在使用非阻塞IO中,也常常使用poll、select、epoll系统调用。三者本质上一致:允许进程决定是否可以对一个或者多个打开的文件做非阻塞的读取或者写入。当使用poll(select、epoo样,下面以poll为例)时,会进行阻塞,知道打开给定的文件集有可以进行读取、写入。常常用于需要多个输入或者输出流而又不会阻塞于其中任何一个流的应用程序中。在应用程序中调用poll系统调用,会将所有给定的文件集进行监控,直到有能用的或者超时返回,poll系统调用原型如下: 其中struct pollfd为:

zichuanning520的博客 1167

光模块MCU开发全解析:从架构原理到固件调试实战

在高速光模块中,MCU并非传统印象里的核心处理器,而是负责数字诊断、闭环控制和协议管理的嵌入式管家。随着800G、1.6T模块的普及,MCU与DSP/SoC的协同、I2C总线通信、ADC采集、APC/TEC控制等低速域任务愈发关键。理解MCU的选型规格、启动流程和固件设计,是保障光模块稳定运行的基础。本文从光模块架构切入,剖析MCU的角色定位,详细拆解I2C从机实现、电芯片配置、校准与升级等工程细节,并结合实际调试经验梳理常见故障与排查思路,为嵌入式工程师提供一份可落地的光模块MCU开发指南。

weixin_29192365的博客 366

selet 语句详解

SELECT 语句的基本格式为: SELECT 要查询的列名 FROM 表名字 WHERE 限制条件; 2.0 数学符号条件 SELECT 语句常常会有 WHERE 限制条件,用于达到更加精确的查询。WHERE限制条件可以有数学符号 (=,<,>,>=,<=) 3.0 AND 与 OR ...

aibeng2705的博客 385

Cadence SIP Layout 简单教程-第一章

以摄像头模组软硬结合板为例,描述layout的整个完整过程,从而掌握基本技能。 第一章 准备工作 第一节 原理图不用说layout前需要绘制原理图,原理图不在本文讨论范围内,所以列为准备工作。 需要特别说明的是,绘制原理的最终目的是导出网络表,网络表中的重要参数footprint是让layout软件选择正确封装的关键,所以这里讲解一下原理图设置footprint的位置。在原理图中双击零件,...

whp1920的博客 1万+

如何用Lmcache+vllm优化KVcache存储?CPU与SSD性能实测对比

本文通过实测对比,详细介绍了如何利用Lmcache+vLLM将大模型推理中的KV Cache卸载至CPU内存或SSD硬盘,以解决长上下文场景下的GPU显存瓶颈。测试数据显示,CPU卸载方案在首字延迟(TTFT)上显著优于SSD方案,但SSD方案在存储成本上更具优势。文章提供了完整的配置指南、性能数据分析和生产环境选型建议。

fire9的博客 990

select()函数的作用

select()在SOCKET编程中还是比较重要的,可是对于初学SOCKET的人来说都不太爱用select()写程序,他们只是习惯写诸如 conncet()、accept()、recv()或recvfrom()这样的阻塞程序(所谓阻塞方式block,顾名思义,就是进程或是线程执行到这些函数时必须等待某个事件发生,如果事件没有发生,进程或线程就被阻塞,函数不能立即返回)。可是使用select()就可...

大东 4万+

人工智能在高中教育中的应用现状剖析与挑战应对

人工智能在高中教育中的应用现状剖析与挑战应对

燕鹏 1341

numpy高级函数操作之——select、choose

一、什么是np.select() 顾名思义,这个函数用用来“ 根据某一些条件 ” 来筛选出 “某一些元素 ”的函数,比如我有一个数组,我如果用if-else语句去做,当然也可以,比如我们让小于6的元素各自加上10,大于等于6的元素统统变为100,我们可以这么做,代码如下: a=np.array([1,2,3,4,5,6,7,8,9,10]) aaa=[] #存储筛选结果的列表 fo...

MIss-Y的博客 2万+

YOLOv8改进,MobileNetV3轻量化架构改进特征提取网络,助力涨点

MobileNetV3通过结合硬件感知网络架构搜索(NAS)和NetAdapt算法,通过新颖的架构改进进一步提升了性能。本文开始探讨了自动化搜索算法与网络设计如何协同工作,以利用互补方法来提升整体技术水平。通过这一过程,创建了两个新的MobileNet模型:MobileNetV3-Large和MobileNetV3-Small,分别针对高资源和低资源使用场景。这些模型随后被适配并应用于目标检测和语义分割任务。

在职AI算法工程师,擅长计算机视觉,YOLO目标检测、分割等,擅长web、pyqt界面可视化,好内容持续更新中,来这里跟大家一起学习,共同进步 3836

汽车UDS诊断之诊断会话控制服务(0x10)深度剖析

DiagnosticSessionControl就是诊断会话控制。 请求消息定义 A_Data类型 参数名称 Cvt 字节值 助记符 #1 诊断会话控制请求SID M 0x10 DSC #2 子功能=[诊断会话类型] M 0x00-0xFF LEV_DS_ ...

心骗小白话的博客 7421

新手必看 SELECT--SQL语法 别乱提问了,先看看

从一个或多个表中检索数据。SELECT SQL 命令是与其它 Visual FoxPro 一样的内置的 Visual FoxPro 命令。当你使用 SELECT 来生成查询时, Visual FoxPro 翻译查询并从表中获取指定数据。你可以从以下地方创建 SELECT 查询:“命令”窗口中 带有其它任何 Visual FoxPro 命令的 Visual FoxPro 程序中 查询设计器中 SEL...

li12684的专栏 3149

交货单冲销发货过账的正确姿势:用 VL09 与 ABAP 批量反冲 Goods Issue

摘要 本文详细解析了SAP系统中VL09事务码的技术实现与业务应用。VL09用于反冲发货的货物移动,通过标准冲销路径(移动类型602冲销601)确保单据链路一致、状态机正确回退和业务规则生效。文章对比了经典VL09与Fiori应用在不同SAP产品形态中的位置,并针对STO场景提供了ME23N验证方法。核心内容包括WS_REVERSE_GOODS_ISSUE函数模块的调用要点、必须COMMIT的原因(SAP LUW机制),以及处理Handling Unit等限制条件的注意事项。最后给出了将VL09工程化的项目

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 595

selet/poll/epoll

所谓linux下一切皆文件,就是从这个上面体现,其中sock通信都是以文件描述符 int类型 fd传递的。其中 0 ,1,2 被系统占用,默认从3开始。其中io(也就是fd)可以被回收,回收的时间是60秒。

wkx0605的博客 647

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

彻底搞懂 select/poll/epoll,就这篇了

在这个模式下epoll遍历ready_list的时候,会把socket从ready_list里面移除,然后读取这个scoket的事件,如果这个socket返回了感兴趣的事件,那么当前这个socket会再被加入到ready_list中,这样下次调用epoll_wait的时候,还能拿到这个socket。如果此时一个客户端同时发来了5个数据包,按正常的逻辑,只需要唤醒一次epoll,把当前socket加一次到ready_list就行了,不需要加5次。...

m0_72730471的博客 165

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

select-poll-epoll的简介和区别

select、poll、epoll简介epoll跟select都能提供多路I/O复用的解决方案。在现在的Linux内核里有都能够支持,其中epoll是Linux所特有,而select则应该是POSIX所规定,一般操作系统均有实现 select:select本质上是通过设置或者检查存放fd标志位的数据结构来进行下一步处理。这样所带来的缺...

as3522的博客 146

socket编程 及select poll epoll示例

1、关于字节排序    网际协议采用大端字节序,来传输多字节整数。    系统提供了转换的宏定义,如果主机与网际协议相同,则宏定义为空。 2、客户端    socket -> connect(阻塞,三次握手)-> rcv 3、服务器端    socket -> bind -> listen -> accept(阻塞,三次握手)-> send4、函数介绍          a..socket 

迷路的专栏 1055

【Linux 事件驱动模型】selet/epoll 里程碑意义记录

具体来说,当进程调用select/epoll系统调用时,内核会将进程的文件描述符集合复制到内核空间,并使用poll_wait函数将进程添加到每个文件描述符对应的等待队列中。当有事件发生时,内核会使用中断或轮询等机制来感知事件的发生,并将发生事件的文件描述符集合传递给select/epoll系统调用的核心函数,让它检查哪些文件描述符有事件发生。当中断发生时,内核会调用中断处理程序来处理事件,并将发生事件的文件描述符集合传递给select/epoll系统调用的核心函数。

Michael 276

结合内核实现源码分析 select poll epoll区别

在博客中以前的文章有介绍epoll的使用方法,但是并没有详细介绍之间的区别 http://blog.youkuaiyun.com/yusiguyuan/article/details/15027821 http://blog.youkuaiyun.com/yusiguyuan/article/details/15029465 http://blog.youkuaiyun.com/yusiguyuan/article

rock_joker的博客 393

Linux IO模式及 select、poll、epoll详解

一 概念说明 在进行解释之前,首先要说明几个概念: - 用户空间和内核空间 - 进程切换 - 进程的阻塞 - 文件描述符 - 缓存 I/O 用户空间与内核空间 现在操作系统都是采用虚拟存储器,那么对32位操作系统而言,它的寻址空间(虚拟存储空间)为4G(2的32次方)。操作系统的核心是内核,独立于普通的应用程序,可以访问受保护的内存空间,也有访问底层

JAVA老菜鸟的博客 315

(Linux与计算机网络)IO模型

当我们想要进行IO操作时,不一定有数据让我们读取,也不一定有空间放我们写入的数据,所以IO操作除了要拷贝数据,还要等待时机,即等待数据或者空间就绪。IO效率高指的是单位时间内传输的数据量大。IO效率低下一般是由于等待的时间过长。因此,阻塞IO和非阻塞IO的IO效率是没有区别的,只是后者可以利用等待的时间去做其它事,提高了整理的效率,但没有提高IO的效率。IO肯定需要等待时机,但是不同的IO模型处理等待的方式不同。很简单,就是一直检测是否就绪,一直等,

Bruce_Arthur的博客 475

select用法&原理详解(源码剖析)

最近刚接触Linux下的select用法,查阅了很多资料终于懂得了一丁点,故将自己查阅后有用的资料整理在这下面。博客链接都是很有价值,写的很好的文章。在研读源码时主要看的是这篇文章:深入select多路复用内核源码加驱动实现 自己能力精力有限,没有办法自己写一篇完完整整的文章,故只能当个搬运工了,文章先后顺序尽量按照了知识点的先后~~如果有什么问题欢迎一起探讨学习~ 前期知识 在开始接触s...

zhougb3的博客 7万+

高并发网络编程之epoll详解

http://www.cricode.com/3499.html

freedom8531的专栏 5039

【校招 --阶段二 linux操作系统】高级I/O多路转接之epoll

epoll与之相关的系统调用 epoll_create 头文件#include<sys/epoll.h> 函数原型: int epoll_create(int size); 参数: size:szie是一个忽略的值,但是必须大于0 返回值是一个文件描述符新epoll实例的文件描述符 调用epoll_create他在底层做了什么?他在操作系统层面上创建一个epoll模型,这个epoll模型用文件描述符访问 epoll_stl 函数原型: int epoll_ctl(int epfd, int

qq_50408340的博客 1045

epoll原理详解及epoll反应堆模型

  设想一个场景:有100万用户同时与一个进程保持着TCP连接,而每一时刻只有几十个或几百个TCP连接是活跃的(接收TCP包),也就是说在每一时刻进程只需要处理这100万连接中的一小部分连接。那么,如何才能高效的处理这种场景呢?进程是否在每次询问操作系统收集有事件发生的TCP连接时,把这100万个连接告诉操作系统,然后由操作系统找出其中有事件发生的几百个连接呢?实际上,在Linux2.4版本以前,...

青萍之末的博客 11万+

Linux-io多路复用

IO多路复用允许单线程高效监测多个文件描述符的IO就绪状态,广泛用于TCP服务器处理多客户端请求及阻塞设备的非阻塞IO。Linux提供select与epoll两种机制:select采用轮询方式,最大支持1024个fd,性能随数量增加下降;epoll基于事件驱动,使用红黑树管理fd,通过内核主动通知就绪事件,支持海量监听,时间复杂度O(1),且仅返回就绪列表,避免无效遍历,显著提升效率。

2401_86256335的博客 221

Java基础:BIO、NIO 与 AIO 和 I/O 多路复用

以网络连接为例,socket 创建、绑定和监听后,可以把监听 socket 注册到 epoll。Linux epoll 将事件注册与等待分开:先创建 epoll 实例,再通过 epoll_ctl 注册或修改关注的 fd 和事件,最后调用 epoll_wait 获取就绪事件。一个选择器能够监听多个通道,当事件就绪时,应用取得对应的 SelectionKey 并处理。select 每次调用传入 fd 集合,内核检查就绪状态,返回后应用也需要检查结果。内核需要检查传入的 fd,应用也需遍历结果;

cjpabc的博客 223
上一篇: 大厂的人自带光环,但光环是从哪儿来的呢?——一位中年Java程序员的感慨
下一篇: Spring Cloud Kubernetes实战之配置管理(附代码实现)
JavaCaiy
博客等级 码龄6年 1万+粉丝 95原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值