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

Linux网络——IO模型和多路转接

通常所谓的IO,其本质就是等待通信和进行通信,即IO = 等 + 拷贝。

那么想要做到高效的IO,就要在单位时间内,减少“等”的比重。


一.五种IO模型

  1. 阻塞 IO: 在内核将数据准备好之前, 系统调用会一直等待. 所有的套接字, 默认都是阻塞方式。阻塞 IO 是最常见的 IO 模型。
  2. 非阻塞 IO: 如果内核还未将数据准备好, 系统调用仍然会直接返回, 并且返回EWOULDBLOCK 错误码. 非阻塞 IO 往往需要程序员循环的方式反复尝试读写文件描述符, 这个过程称为轮询. 这对 CPU 来说是较大的浪费, 一般只有特定场景下才使用。
  3. 信号驱动 IO: 内核将数据准备好的时候, 使用 SIGIO 信号通知应用程序进行 IO 操作.
  4. IO 多路转接: 和阻塞 IO 类似. 核心在于 IO 多路转接能够同时等待多个文件描述符的就绪状态。
  5. 异步 IO: 由内核在数据拷贝完成时, 通知应用程序(而信号驱动是告诉应用程序何时可以开始拷贝数据)。

此处展开分享一下非阻塞IO。 


二.非阻塞IO

系统和网络中的文件描述符,其默认情况下都是阻塞IO,下面来看怎么将其设置为非阻塞IO。


1.fcntl函数

#include <unistd.h>

#include <fcntl.h>

int fcntl(int fd, int cmd, ... /* arg */ );

fcntl 函数有 5 种功能:

  • 复制一个现有的描述符(cmd=F_DUPFD.
  • 获得/设置文件描述符标记(cmd=F_GETFD F_SETFD).
  • 获得/设置文件状态标记(cmd=F_GETFL F_SETFL).
  • 获得/设置异步 I/O 所有权(cmd=F_GETOWN F_SETOWN).
  • 获得/设置记录锁(cmd=F_GETLK,F_SETLK F_SETLKW).

此处只是用第三种功能, 获取/设置文件状态标记, 就可以将一个文件描述符设置为非阻塞。


2.代码实现非阻塞

void SetNoBlock(int fd)
{int fl = fcntl(fd, F_GETFL);if (fl < 0){perror("fcntl");return;}fcntl(fd, F_SETFL, fl | O_NONBLOCK);
}

使用 F_GETFL 将当前的文件描述符的属性取出来(这是一个位图)。

然后再使用 F_SETFL 将文件描述符设置回去. 设置回去的同时, 加上一个 O_NONBLOCK 参数,表示为非阻塞

前边提到,在非阻塞IO下,如果数据没有就绪,那么IO就会以出错的形式返回,那么如何区分到底是数据没有就绪,还是真的出错了呢???

通过判断errno错误码,如果错误码为EWOULDBLOCK,表示数据没有就绪,此时可以设计程序去做其他事,并通过轮询方式去检测数据是否就绪,反之则为真的出错,程序退出。

此外,如果进程长期阻塞,可能会收到系统的信号,中断程序运行,此时返回的错误码为EINTR,所以如果不想程序被系统中断,就可以通过此错误码在做判断。


三.多路转接

多路转接,即等待多个fd上的新事件就绪,然后通知程序员,事件已经就绪,可以进行IO拷贝了。


1.select

(1)概述

系统提供 select 函数来实现多路复用输入/输出模型。

  • select 系统调用是用来让我们的程序监视多个文件描述符的状态变化的;
  • 程序会停在 select 这里等待,直到被监视的文件描述符有一个或多个发生了状态改变;

IO = 等 + 拷贝,select负责的就是等待,并且是等待多个新事件的到了。


(2)接口

#include <sys/select.h>

int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout);

参数:

  • nfds :是需要监视的最大的文件描述符值+1
  • rdset,wrset,exset :分别对应于需要检测的可读文件描述符的集合,可写文件描述符的集合及异常文件描述符的集合,是输入输出型参数。
  • timeout :为结构体 timeval类型,用来设置 select()的等待时间。

fd_set结构:

这个结构就是一个整数数组, 更严格的说,是一个 "位图",使用位图中对应的位来表示要监视的文件描述符。

  • 输入时,比特位的位置表示文件描述符的编号,比特位的内容表示是否关心该fd事件。
  • 输出时,比特位的位置表示文件描述符的编号,比特位的内容表示对应的fd事件是否发生。

下面是OS提供了一组操作 fd_set 的接口, 来比较方便的操作位图:

void FD_CLR(int fd, fd_set *set); // 用来清除描述词组 set 中相关 fd 的位

int FD_ISSET(int fd, fd_set *set); // 用来测试描述词组 set 中相关 fd 的位是否为真

void FD_SET(int fd, fd_set *set); // 用来设置描述词组 set 中相关 fd 的位

void FD_ZERO(fd_set *set); // 用来清除描述词组 set 的全部位

timeval结构:

struct timeval

{

        __time_t tv_sec;//秒

        __suseconds_t tv_usec;//微秒
}

timeval 结构用于描述一段时间长度,比如(5,0)则表示在0-5秒内;如果在这个时间内,需要监视的描述符没有事件发生则函数返回,返回值为 0。

参数 timeout 取值:

  • nullptr:则表示 select()没有 timeoutselect 将一直被阻塞,直到某个文件描述符上发生了事件;
  • 0:仅检测描述符集合的状态,然后立即返回,并不等待外部事件的发生,即按照非阻塞轮询的方式。
  • 特定的时间值:如果在指定的时间段里没有事件发生,select 将超时返回。

函数返回值:

  • 执行成功则返回文件描述词状态已改变的个数。
  • 如果返回 0 代表在描述词状态改变前已超过 timeout 时间,没有返回。
  • 当有错误发生时则返回-1,错误原因存于 errno,此时参数 readfdswritefds, exceptfds 和 timeout 的值变成不可预测。

(3)缺点

每次调用 select,都需要手动设置 fd 集合, 从接口使用角度来说也非常不便。

每次调用 select,都需要把 fd 集合从用户态拷贝到内核态,这个开销在 fd 很多时会很大。

同时每次调用 select 都需要在内核遍历传递进来的所有 fd,这个开销在 fd 多时也很大。

select 支持的文件描述符数量太小。


2.poll

(1)概述

poll的作用与select完全相同,也是等待多个fd,等待fd上的新事件就绪,随后派发事件,可以理解为是select的优化版本。


(2)接口

#include <poll.h>

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

参数:

  •  fds是一个 poll 函数监听的结构列表. 每一个元素中, 包含了三部分内容: 文件描述符, 监听的事件集合, 返回的事件集合。

  • nfds 表示 fds 数组的长度。

  • timeout:以毫秒为单位,设定的超时时间,设为0表示非阻塞,-1表示阻塞。

pollfd结构体:

struct pollfd {

int

fd; /* file descriptor */

short events; /* requested events */

short revents; /* returned events */

};

同样是位图结构,short16位,每一位可代表一个事件,eventsrevents的取值: 

 这些事件都是,且分别表示为不同的二进制位,因此可以自由组合搭配,形成事件集合。

返回值:

  • 大于0,表示有几个fd就绪。
  • 等于0,超时。
  • 小于0,poll出错。

(3)优点

pollfd 结构包含了要监视的 event 和发生的 event,不再使用 select“参数-传递的方式. 接口使用比 select 更方便。

poll 并没有最大数量限制 (但是数量过大后性能也是会下降)。


3.epoll

(1)概述

epoll是除了select和poll之外公认为 Linux 下性能最好的多路 I/O 就绪通知方法。


(2)接口

使用epoll接口需要包含头文件 #include<sys/epoll.h>。 

int epoll_create(int size);

创建一个 epoll 的句柄.

  • size 参数可以被忽略。
  • 用完之后, 必须调用 close()关闭。

返回值epfd供接下来的函数使用。

int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event);

epoll 的事件注册函数. 它不同于 select()是在监听事件时告诉内核要监听什么类型的事件, 而是在这里先注册要监听的事件类型。

epoll_ctl在底层会将用户让内核关心的fd及其事件添加进由内核构成的红黑树中进行维护。

  • 第一个参数是 epoll_create()的返回值(epoll 的句柄).
  • 第二个参数表示动作,用三个宏来表示.
  • 第三个参数是需要监听的 fd.
  • 第四个参数是告诉内核需要监听什么事.

第二个参数的取值:

  • EPOLL_CTL_ADD:注册新的 fd epfd 中;
  • EPOLL_CTL_MOD:修改已经注册的 fd 的监听事件;
  • EPOLL_CTL_DEL:从 epfd 中删除一个 fd

struct epoll_event 结构如下:

typedef union epoll_data {
        void *ptr;
        int fd;
        uint32_t u32;
        uint64_t u64;
} epoll_data_t;

        struct epoll_event {
        uint32_t events;/* Epoll events */
        epoll_data_t data;/* User data variable */
};

需要关注一下epoll_data_t结构体中的fd成员,其要存放事件的fd,当后续事件就绪时,需要通过该fd来获取事件

其中events同样为位图结构,可以是以下几个宏的集合:

  • EPOLLIN : 表示对应的文件描述符可以读 (包括对端 SOCKET 正常关闭);
  • EPOLLOUT : 表示对应的文件描述符可以写;
  • EPOLLPRI : 表示对应的文件描述符有紧急的数据可读 (这里应该表示有带外数据到来);
  • EPOLLERR : 表示对应的文件描述符发生错误;
  • EPOLLHUP : 表示对应的文件描述符被挂断;
  • EPOLLET : EPOLL 设为边缘触发(Edge Triggered)模式, 这是相对于水平触发(Level Triggered)来说的.
  • EPOLLONESHOT:只监听一次事件, 当监听完这次事件之后, 如果还需要继续监听这个 socket 的话, 需要再次把这个 socket 加入到 EPOLL 队列里.

int epoll_wait(int epfd, struct epoll_event * events, int maxevents, int timeout);

收集在 epoll 监控的事件中已经发送的事件.

epoll_wait会检测内核中构成的就绪队列中是否有事件已经就绪, 并将已经就绪的事件按照严格顺序放入我们定义的用户缓冲区数组中。

  • 参数 events 是分配好的 epoll_event 结构体数组. epoll 将会把发生的事件赋值到 events 数组中 (events 不可以是空指针,内核只负责把数据复制到这个 events 数组中,不会去帮助我们在用户态中分配内存).
  • maxevents 告诉内核这个 events 有多大,这个 maxevents 的值不能大于创建 epoll_create()时的 size.
  • 参数 timeout 是超时时间 (毫秒,0 会立即返回,-1 是永久阻塞).
  • 如果函数调用成功,返回对应 I/O 上已准备好的文件描述符数目,如返回 0 表示已超时, 返回小于 0 表示函数失败.

对应的事件节点,会同时包含红黑树和就绪队列两个指针,从而使得该节点既可以存在于红黑树中,也可以存在于就绪队列中,从而无需新建新节点来进行转移。 


(3)LT工作模式

LT即水平触发 Level Triggered 工作模式。

epoll 默认状态下就是 LT 工作模式.

当 epoll 检测到 socket 上事件就绪的时候, 可以不立刻进行处理,或者只处理一部分,当缓冲区还有事件未处理时,epoll_wait 会不断地立刻返回并通知 socket 读事件就绪,直到缓冲区上所有的数据都被处理完, epoll_wait 才不会立刻返回。

支持阻塞读写和非阻塞读写。


(4)ET工作模式

ET即边缘触发 Edge Triggered 工作模式。

在第 1 步将 socket 添加到 epoll 描述符的时候使用 EPOLLET 标志, epoll 将进入 ET 工作模式。

当 epoll 检测到 socket 上事件就绪时, 必须立刻处理。如果未处理或未一次性处理完,在第二次调用epoll_wait 的时候, epoll_wait 不会再返回了。

也就是说, ET 模式下, 文件描述符上的事件就绪后, 只有一次处理机会。

ET 的性能比 LT 性能更高( epoll_wait 返回的次数少了很多). Nginx 默认采用 ET 模式使用 epoll。

只支持非阻塞的读写。


LT epoll 的默认行为.

使用 ET 能够减少 epoll 触发的次数. 但是代价就是强逼着程序猿一次响应就绪过程中就把所有的数据都处理完.

相当于一个文件描述符就绪之后, 不会反复被提示就绪, 看起来就比 LT 更高效一些. 是在 LT 情况下如果也能做到每次就绪的文件描述符都立刻处理, 不让这个就绪被重复提示的话, 其实性能也是一样的.

另一方面, ET 的代码复杂程度更高。


相关文章:

Linux网络——IO模型和多路转接

通常所谓的IO&#xff0c;其本质就是等待通信和进行通信&#xff0c;即IO 等 拷贝。 那么想要做到高效的IO&#xff0c;就要在单位时间内&#xff0c;减少“等”的比重。 一.五种IO模型 阻塞 IO: 在内核将数据准备好之前, 系统调用会一直等待. 所有的套接字, 默认都是阻塞方…...

浅谈网络 | 应用层之HTTP协议

目录 HTTP 请求的准备HTTP 请求的构建HTTP 请求的发送过程HTTP 返回的构建HTTP 2.0QUIC 协议HTTP 3.0 在讲完传输层之后&#xff0c;我们接下来进入应用层的内容。应用层的协议种类繁多&#xff0c;那从哪里开始讲起呢&#xff1f;不妨从我们最常用、最熟悉的 HTTP 协议 开始。…...

【CSS】页面滚动到一定位置时,指定区域固定不变

一. 需求 移动端&#xff1a;下滑时&#xff0c;当下滑到一定位置时&#xff0c;指定区域不跟随下滑-【固定跟随区域】一直在顶部效果 &#xff08;1&#xff09;未滚动前 &#xff08;2&#xff09;滚动后 二. 实现 <template><div class"global-application…...

瀚高创库建表pgsql

1.瀚高下载地址&#xff1a; 下载 (highgo.com)https://www.highgo.com/down_main.html 2.瀚高linux安装 上传deb文件到ubuntu系统中 执行 dpkg -i hgdb-see-4.5.8-fe4791c.x86_64.deb 命令安装数据库 安装完成后&#xff0c;会在/opt 目录下生成安装目录 数据库安装完毕后…...

Vim 高级操作与技巧指南

在上一篇文章中&#xff0c;我们了解了 Vim 的基本操作和模式&#xff0c;掌握了如何进行文件编辑、光标移动、文本操作等基本技能。现在&#xff0c;我们将深入探讨 Vim 的一些高级功能&#xff0c;包括插件管理、脚本编写、定制快捷键等内容&#xff0c;以进一步提高你的工作…...

Vue3.0里为什么要用 Proxy API 替代 defineProperty API ?

Vue 3.0 之所以使用 Proxy API 替代 Object.defineProperty,主要是为了提升性能、减少代码复杂性,并解决 Vue 2.x 在响应式处理中的一些局限性。下面我们通过对比这两种方式的工作原理、优缺点,并结合实际项目代码示例来详细讲解。 1. Object.defineProperty 的局限性 在 …...

【基于规则】n-sigma

在正态分布中: 约68%的数据点会落在均值1σ的范围内约95%的数据点会落在均值2σ的范围内约99.7%的数据点会落在均值3σ的范围内这称为68-95-99.7法则(Empirical Rule)。 假设我们有一组数据,其均值为μ,标准差为σ。某个数据点x的n-sigma计算公式如下: 若z=1.2,说明该…...

JavaScript 判断字符串是否包含子字符串的几种方法

这里写目录标题 方法 1: 使用 includes()方法 2: 使用 indexOf()方法 3: 使用正则表达式方法 4: 使用 search()方法 5: 用 startsWith() 或 endsWith()推荐使用 JavaScript 判断字符串是否包含子字符串&#xff0c;不要只知道 indexOf() &#xff0c;还可以尝试一下其他写法。 …...

goframe框架bug-记录

implement not found for interface ICompany, forgot register? 错误解决检查&#xff1a; 1.有没有init 2. 注入问题 3. 注入问题...

Docker:在 ubuntu 系统上生成和加载 Docker 镜像

本文将介绍在 ubuntu系统上进行 Docker 镜像的生成和加载方法和代码。 文章目录 一、下载和安装 docker二、加载 docker 文件三、保存你的镜像四、将镜像上传到云端并通过连接下载和加载 Docker 镜像五、Docker 容器和本地的文件交互5.1 从容器复制文件到本地宿主机5.1.1 单个文…...

长时间无事可做是个危险信号

小马加入的是技术开发部&#xff0c;专注于Java开发。团队里有一位姓隋的女同事&#xff0c;是唯一的web前端工程师&#xff0c;负责页面开发工作&#xff0c;比小马早两个月入职。公司的项目多以定制化OA系统为主&#xff0c;后端任务繁重&#xff0c;前端工作相对较少。在这样…...

【小白学机器学习39】如何用numpy生成总体,生成样本samples

目录 1 目的&#xff1a;研究 样本和总体之间的关系 2 先生成1个理论总体 2.0 下面是关于这一步的完整代码 2.1 一般情况下&#xff0c;我们先生成一个符合正态分布的总体 2.1.1 设置总体 &#xff0c;或者说生成一个总体 2.2 为什么一定要是一个符合正态分布的总体&…...

redis的主从复制

redis主从复制 一、主从复制概念二、主从模式运行原理2.1主从复制的演示&#xff1a;2.2查看主从结构信息&#xff1a;2.3AOF文件对主从关系的影响2.4主从节点建立复制流程图 三、主从复制的拓扑结构3.1 一主一从结构3.2 一主多从结构3.3 树形主从结构 四、数据同步psync4.1全量…...

数据结构与算法(排序算法)

排序的概念 1. 排序是指将一组数据&#xff0c;按照特定的顺序进行排列的过程。 2. 这个过程通常是为了使数据更加有序&#xff0c;从而更容易进行搜索、比较或其他操作。 常见的排序算法 插入排序 1. 把待排序的记录&#xff0c;按其关键码值的大小&#xff0c;逐个插入到一…...

极狐GitLab 17.6 正式发布几十项与 DevSecOps 相关的功能【三】

GitLab 是一个全球知名的一体化 DevOps 平台&#xff0c;很多人都通过私有化部署 GitLab 来进行源代码托管。极狐GitLab 是 GitLab 在中国的发行版&#xff0c;专门为中国程序员服务。可以一键式部署极狐GitLab。 学习极狐GitLab 的相关资料&#xff1a; 极狐GitLab 官网极狐…...

三格电子—EtherNet IP转Modbus RTU网关

EtherNet/IP转Modbus RTU网关 SG-EIP-MOD-210 产品用途 SG-EIP-MOD-210网关可以实现将Modbus接口设备连接到 EtherNet/IP网络中。用户不需要了解具体的Modbus和 EtherNet/IP协议即可实现将Modbus设备挂载到 EtherNet/IP接口的PLC上&#xff0c;并和Modbus设备进行数据交互。拓…...

centos7下安装haproxy2.2

1、安装epel yum install epel-release2、下载并安装ius的centos7软件镜像 wget https://repo.ius.io/ius-release-el7.rpm rpm -ivh ius-release-el7.rpm3、安装haproxy yum search haproxy yum install haproxy224、启动服务 systemctl status haproxy systemctl start h…...

Spring Boot英语知识网站:安全与维护

摘要 随着信息技术在管理上越来越深入而广泛的应用&#xff0c;管理信息系统的实施在技术上已逐步成熟。本文介绍了英语知识应用网站的开发全过程。通过分析英语知识应用网站管理的不足&#xff0c;创建了一个计算机管理英语知识应用网站的方案。文章介绍了英语知识应用网站的系…...

PHP实现终端表格提取

背景 刚开始使用restic想要获取终端的输出数据,默认的终端信息如下示例 restic snapshotsrepository 5816ba52 opened (version 2, compression level auto) ID Time Host Tags Paths Size ------------------------------------…...

c++ 拓扑排序

概念 拓扑排序是一种线性排序算法&#xff0c;主要用于有向无环图 (DAG, Directed Acyclic Graph) 中&#xff0c;对顶点进行排序&#xff0c;使得对于每一条边 u→v&#xff0c;顶点 u 都排在顶点 v之前。 特点 适用于有向无环图。 拓扑排序的结果不唯一&#xff08;如果有…...

Vue3的双向数据绑定

如果你有多个 ref 类型的数据需要在父子组件之间实现双向绑定&#xff0c;可以使用 v-model 来进行多个数据的双向绑定。在 Vue 3 中&#xff0c;v-model 默认是针对 modelValue 的&#xff0c;但你可以通过指定自定义的属性名来实现多个双向绑定。 多个 v-model 双向绑定的实…...

android-sdk 安装脚本、android-sdk(和platform-tools)国内镜像

android-sdk国内镜像 https://mirrors.cloud.tencent.com/AndroidSDK/ android-sdk安装脚本 android-sdk 安装脚本 androidSdk_install.sh #!/bin/bash #[描述] android-sdk 安装# set -eu shopt -s expand_aliasesAndroid_SDK_D/app5/android-sdk-home/JAVA17_D/app/zulu17…...

SAR ADC 系列16:基于运放的高精度比较器

高精度比较器的设计目标 静态开环运放比较器 共模为&#xff0c;Id*R1&#xff0c;不稳定&#xff0c;随Id和R1变化。 正反馈。Vin增加&#xff0c;Vout-减小 推推推推推&#xff0c;Vout-又减小&#xff0c;正反馈 同时&#xff0c;MP2 < MP1 时&#xff0c;增益提升。MP…...

spring boot 调用C#封装的DLL文件中的函数

1、C#方法 using Infrastructure; using System.Runtime.InteropServices; using System.Text; using System.Text.Json;namespace PH.Resistance;/// <summary> /// 预热器 阻力计算 /// </summary> public class PHResistance {private double? C1_outlet_YP01…...

《C++ 与神经网络:自动微分在反向传播中的高效实现之道》

在深度学习蓬勃发展的今天&#xff0c;神经网络成为了众多领域的核心技术驱动力。而反向传播算法作为训练神经网络的关键手段&#xff0c;其背后的自动微分技术的高效实现尤为重要&#xff0c;特别是在 C 这样追求性能与内存控制极致的编程语言环境下。 神经网络通过大量的参数…...

AppFlow:支持飞书机器人调用百炼应用

AppFlow&#xff1a;支持飞书机器人调用百炼应用 简介&#xff1a; 本文介绍了如何创建并配置飞书应用及机器人&#xff0c;包括登录飞书开发者后台创建应用、添加应用能力和API权限&#xff0c;以及通过AppFlow连接流集成阿里云百炼服务&#xff0c;最后详细说明了如何将机器…...

Axure RP教程:创建高效用户界面和交互

Axure RP是一款广受好评的软件&#xff0c;专门用于设计精致的用户界面和交互体验。这款软件提供了众多UI控件&#xff0c;并根据它们的用途进行了分类。与此同时&#xff0c;国产的即时设计软件作为Axure的替代品&#xff0c;支持在线协作和直接在浏览器中使用&#xff0c;无需…...

【Bug】el-date-picker组件时间差

这个组件默认是国际标准时间 2024-11-27T07:56:37.000Z 表示的是 UTC 时间。如果你当前所在的时区是 UTC8&#xff08;例如中国&#xff09;&#xff0c;那么这个时间实际上是比你选择的时间早 8 个小时 T表示分隔符&#xff0c;Z表示的是UTC 解决&#xff1a;给el-date-pic…...

Ubuntu问题 -- 使用scp将本机文件传输至ubuntu服务器中

目的 临时没有文件传输工具使用一条命令快速传输指定文件或文件夹 使用scp命令 传输指定文件 scp -P 22 D:\Storage\myCache\UE\Linux_ue_demo.zip txl10.1.112.93:/home/txl-P是远程机器的ssh端口号, SCP&#xff08;安全复制协议&#xff09;使用和SSH&#xff08;安全外壳…...

每日速记10道java面试题02

其他面试题 每日速记10道java面试题01-CSDN博客 目录 一、Java 中 String、StringBuffer 和 StringBuilder 的区别是什么? 二、java的Stringbuilder是怎么实现的&#xff1f; 三、Java 中包装类型和基本类型的区别是什么? 四、接口和抽象类有什么区别&#xff1f; ​编辑…...

解决 Vim 上下左右变成 ABCD 的问题

解决 Vim 上下左右变成 ABCD 的问题 Vim 是 Linux 和 Unix 系统上广受欢迎的编辑器&#xff0c;但许多用户在首次使用时会遇到一些让人困惑的问题&#xff0c;例如&#xff1a;按下上下左右键时光标不移动&#xff0c;而是输出 A、B、C、D 字母。这篇文章将深入分析该问题的解…...

并发编程(14)——内存栅栏

文章目录 十四、day141. 内存栅栏1.1 什么是栅栏1.2 栅栏和原子操作的对比1.2.1 获取操作1.2.2 释放操作 1.3 线程可见顺序1.4 通过栅栏保证指令编排顺序1.5 通过栅栏令非原子操作服从内存次序1.6 同步线程间的内存访问 十四、day14 在学习完内存模型、内存序、原子类型、操作…...

消息中间件用途介绍

1. 解耦&#xff08;Decoupling&#xff09;&#xff1a; • 消息中间件能够将消息的生产者&#xff08;Producer&#xff09;和消费者&#xff08;Consumer&#xff09;分离开来&#xff0c;使它们不必直接相互依赖。这种设计降低了系统的耦合度&#xff0c;提升了系统的可扩展…...

Algorithms and Data Structures in C++ by Mohammed Yasir Eramangadan

MP4 创建 |视频&#xff1a;h264、1280720 |音频&#xff1a;AAC&#xff0c;44.1 KHz&#xff0c;2 通道 类型&#xff1a;在线学习 |语言&#xff1a;英文 字幕 |持续时间&#xff1a; 159 讲座 &#xff08; 10h 43m &#xff09; |大小&#xff1a; 3.5 GB “通过专家制作…...

Binder架构

一、架构 如上图&#xff0c;binder 分为用户层和驱动层两部分&#xff0c;用户层有客户端&#xff08;Client&#xff09;、服务端&#xff08;Server&#xff09;、服务管理&#xff08;ServiceManager&#xff09;。 从用户空间的角度&#xff0c;使用步骤如下&#xff08;…...

【第十一课】Rust并发编程(二)

目录 前言 Channel 多生产者 前言 在上一节中&#xff0c;我们介绍了Rust中并发编程的方式之一&#xff1a;Fork和Join&#xff0c;通过新建线程提升代码的效率&#xff0c;这节课我们介绍并发编程的第二种方式&#xff1a;通道。Channel就类似于水管&#xff0c;通过Channe…...

网络知识1-TCP/IP模型

从用户端到服务端&#xff0c;tcp/ip模型可分为应用层、传输层、网络层、网络接口层 以下使用寄快递为例进行解释 应用层职责&#xff1a; 只关注与为用户提供应用功能&#xff0c;如HTTP、FTP、telnet、DNS、SMTP等 &#xff0c;应用层的职责就像我们寄快递时将快递给快递员…...

burpsuite(2)最新版burpsuite安装教程

一、安装Java 1.安装jdk21&#xff0c;直接官网下载 下载链接&#xff1a;Java21 2.cmd 输出java&#xff08;查看java是否已经被安装&#xff09; 3.java -version&#xff08;查看java版本&#xff09; 二、安装burpsuite 4.下载burpsuite最新版本&#xff0c;选择jar方式…...

微知-arp如何删除所有表项?(arp -d; ip neighbor delete 192.168.0.100)

ar命令删掉所有表项 sudo arp -d使用ip命令 ip neighbor delete 192.168.0.100...

使用guzzlehttp异步多进程实现爬虫业务

Python和PHP核心技术共享平台 背景 小哥近来在通过动态代理池爬取一些公司需要的大文件pdf规格书的处理。遇到的难点&#xff0c;如何保证服务器CPU、连接数等正常情况下&#xff0c;多进程、异步快速处理这些业务并且保证准确。下面小哥就给看官唠嗑一下&#xff0c;我使用gu…...

websocket前后端长连接之java部分

一共有4个类,第一个WebSocketConfig 配置类 Configuration EnableWebSocket public class WebSocketConfig implements WebSocketConfigurer {Autowiredprivate WebSocketHandler webSocketHandler;Autowiredprivate WebSocketInterceptor webSocketInterceptor;Overridepubli…...

无线感知会议系列【16】QGesture-1

摘要&#xff1a; 这是2018年发表的一篇 paper 《 Quantifying Gesture Distance and Direction with WiFi Signals》 下一篇重要分享 Decimeter-level localization with a single WiFi access point&#xff0c;主要创新点是如何对CFO SFO PBD 噪声进行去噪。 许多人机交互&…...

如何用通义灵码快速绘制流程图?

使用通义灵码快速绘制流程图&#xff1f;新功能体验 不想读前人“骨灰级”代码&#xff0c;不想当“牛马”程序员&#xff0c;想像看图片一样快速读复杂代码和架构&#xff1f; 通义灵码已经支持代码逻辑可视化&#xff0c;可以把你的每段代码画成流程图。像个脑图工具一样帮你…...

如何搭建一个小程序:从零开始的详细指南

在当今数字化时代&#xff0c;小程序以其轻便、无需下载安装即可使用的特点&#xff0c;成为了连接用户与服务的重要桥梁。无论是零售、餐饮、教育还是娱乐行业&#xff0c;小程序都展现了巨大的潜力。如果你正考虑搭建一个小程序&#xff0c;本文将为你提供一个从零开始的详细…...

wp the_posts_pagination 与分类页面搭配使用

<ul> <?php while( have_posts() ) : the_post(); <li > <a href"<?php the_permalink(); ?>"> <?php xizhitbu_get_thumbnail(thumb-pro); ?> </a> <p > <a href&q…...

文件包含漏洞

本质 本质和SQL注入相同&#xff0c;都是输入一段用户可以控制的脚本或代码&#xff0c;让服务器执行 包含就比如把函数写在一个文件里&#xff0c;调用函数时直接用文件 文件包含漏洞就是攻击者修改了文件的位置&#xff0c;让后台执行任意文件 函数 &#xff08;PHP&…...

docker快速安装zookeeper

一、拉取镜像 docker pull zookeeper:3.9.3 二、启动zookeeper docker run --restartalways -d --name zookeeper -p 2181:2181 -v /etc/localtime:/etc/localtime zookeeper:3.9.3 如果需要挂载zookeeper文件及目录&#xff0c;则参数增加&#xff1a; -v /mydata/zookeeper/d…...

如何解决 java.security.acl.NotOwnerException: 在 ACL 中尝试执行非所有者的操作问题?亲测有效的解决方法!

在 Java 中&#xff0c;java.security.acl.NotOwnerException 异常通常出现在访问控制列表&#xff08;ACL&#xff09;操作中。当你尝试在一个不属于拥有者的实体上执行特定的操作时&#xff0c;Java 安全管理器会抛出此异常。简单来说&#xff0c;它指的是你正在尝试执行一个…...

【电力行业标准】《电力信息化软件工程度量规范》(DL/T 2015-2019)-费用标准解读系列20

《电力信息化软件工程度量规范》&#xff08;DL/T 2015-2019&#xff09;是国家能源局2019年6月4日发布&#xff0c;2019年10月1日实施的电力行业标准&#xff08;了解更多可直接关注我们咨询&#xff09;&#xff0c;规定了电力行业信息化软件工程度量原则与内容、成本构成及各…...

python除了熟悉的pandas,openpyxl库也很方便的支持编辑Excel表

excel表格是大家经常用到的文件格式&#xff0c;各行各业都会跟它打交道。之前文章我们介绍了使用openpyxl和xlrd库读取excel表数据&#xff0c;使用xlwt库创建和编辑excel表&#xff0c;在办公自动化方面可以方便我们快速处理数据&#xff0c;帮助我们提升效率。 python之open…...