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

C++负载均衡远程调用学习之集成测试与自动启动脚本

目录

01 Lars-LbAgentV0.7-route_lb获取路由全部主机信息

02 Lars-LbAgentV0.7-API模块注册功能实现和测试工

03 Lars-LbAgentV0.7-项目构建工具

04 Lars-LbAgentV0.7-启动工具脚本实现

05 Lars-有关fd泄露的调试办法

06 Lars-qps性能测试

07 git企业开发基本流程


01 Lars-LbAgentV0.7-route_lb获取路由全部主机信息

#### C. 测试

启动server

```bash
$ ./lars_reactor 
begin accept
```



启动client    

```bash
$ nc 127.0.0.1 7777
```

客户端输入 文字,效果如下:



服务端:

```bash
ibuf.length() = 21
recv data = hello lars, By Aceld
```



客户端:

```bash
$ nc 127.0.0.1 7777
hello lars, By Aceld
hello lars, By Aceld
```

​    ok!现在我们的读写buffer机制已经成功的集成到我们的lars网络框架中了。

02 Lars-LbAgentV0.7-API模块注册功能实现和测试工

## 4) 事件触发event_loop

​        接下来我们要尝试添加多路IO的处理机制,当然linux的平台下, 最优的选择就是使用epoll来做,但是用原生的epoll实际上编程起来扩展性不是很强,那么我们就需要封装一套IO事件处理机制。

### 4.1 io_event基于IO事件封装

​        我们首先定义一个IO事件类来包括一个时间需要拥有的基本成员信息.

> lars_reactor/include/event_base.h

```cpp
#pragma once
/*
 * 定义一些IO复用机制或者其他异常触发机制的事件封装
 *
 * */

class event_loop;

//IO事件触发的回调函数
typedef void io_callback(event_loop *loop, int fd, void *args);

/*
 * 封装一次IO触发实现 
 * */
struct io_event 
{
             io_event():read_callback(NULL),write_callback(NULL),rcb_args(NULL),wcb_args(NULL) {}

    int mask; //EPOLLIN EPOLLOUT
    io_callback *read_callback; //EPOLLIN事件 触发的回调 
    io_callback *write_callback;//EPOLLOUT事件 触发的回调
    void *rcb_args; //read_callback的回调函数参数
    void *wcb_args; //write_callback的回调函数参数
};
```

​        一个`io_event`对象应该包含 一个epoll的事件标识`EPOLLIN/EPOLLOUT`,和对应事件的处理函数`read_callback`,`write_callback`。他们都应该是`io_callback`类型。然后对应的函数形参。

### 4.2 event_loop事件循环处理机制

​        接下来我们就要通过event_loop类来实现io_event的基本增删操作,放在原生的`epoll`堆中。

> lars_reactor/include/event_loop.h

```h
#pragma once
/*
 *
 * event_loop事件处理机制
 *
 * */
#include <sys/epoll.h>
#include <ext/hash_map>
#include <ext/hash_set>
#include "event_base.h"

#define MAXEVENTS 10

// map: fd->io_event 
typedef __gnu_cxx::hash_map<int, io_event> io_event_map;
//定义指向上面map类型的迭代器
typedef __gnu_cxx::hash_map<int, io_event>::iterator io_event_map_it;
//全部正在监听的fd集合
typedef __gnu_cxx::hash_set<int> listen_fd_set;

class event_loop 
{
public:
    //构造,初始化epoll堆
    event_loop();

    //阻塞循环处理事件
    void event_process();

    //添加一个io事件到loop中
    void add_io_event(int fd, io_callback *proc, int mask, void *args=NULL);

    //删除一个io事件从loop中
    void del_io_event(int fd);

    //删除一个io事件的EPOLLIN/EPOLLOUT
    void del_io_event(int fd, int mask);
    
private:
    int _epfd; //epoll fd

    //当前event_loop 监控的fd和对应事件的关系
    io_event_map _io_evs;

    //当前event_loop 一共哪些fd在监听
    listen_fd_set listen_fds;

    //一次性最大处理的事件
    struct epoll_event _fired_evs[MAXEVENTS];

};
```

03 Lars-LbAgentV0.7-项目构建工具

**属性**:

`_epfd`:是epoll原生堆的fd。

`_io_evs`:是一个hash_map对象,主要是方便我们管理`fd`<—>`io_event`的对应关系,方便我们来查找和处理。

`_listen_fds`:记录目前一共有多少个fd正在本我们的`event_loop`机制所监控.

`_fried_evs`:已经通过epoll_wait返回的被激活需要上层处理的fd集合.

**方法**:

`event_loop()`:构造函数,主要初始化epoll.

`event_process()`:永久阻塞,等待触发的事件,去调用对应的函数callback方法。

`add_io_event()`:绑定一个fd和一个`io_event`的关系,并添加对应的事件到`event_loop`中。

`del_io_event()`:从`event_loop`删除该事件。

04 Lars-LbAgentV0.7-启动工具脚本实现

    具体实现方法如下:

> lars_reactor/src/event_loop.cpp

```cpp
#include "event_loop.h"
#include <assert.h>

//构造,初始化epoll堆
event_loop::event_loop() 
{
    //flag=0 等价于epll_craete
    _epfd = epoll_create1(0);
    if (_epfd == -1) {
        fprintf(stderr, "epoll_create error\n");
        exit(1);
    }
}


//阻塞循环处理事件
void event_loop::event_process()
{
    while (true) {
        io_event_map_it ev_it;

        int nfds = epoll_wait(_epfd, _fired_evs, MAXEVENTS, 10);
        for (int i = 0; i < nfds; i++) {
            //通过触发的fd找到对应的绑定事件
            ev_it = _io_evs.find(_fired_evs[i].data.fd);
            assert(ev_it != _io_evs.end());

            io_event *ev = &(ev_it->second);

            if (_fired_evs[i].events & EPOLLIN) {
                //读事件,掉读回调函数
                void *args = ev->rcb_args;
                ev->read_callback(this, _fired_evs[i].data.fd, args);
            }
            else if (_fired_evs[i].events & EPOLLOUT) {
                //写事件,掉写回调函数
                void *args = ev->wcb_args; 
                ev->write_callback(this, _fired_evs[i].data.fd, args);
            }
            else if (_fired_evs[i].events &(EPOLLHUP|EPOLLERR)) {
                //水平触发未处理,可能会出现HUP事件,正常处理读写,没有则清空
                if (ev->read_callback != NULL) {
                    void *args = ev->rcb_args;
                    ev->read_callback(this, _fired_evs[i].data.fd, args);
                }
                else if (ev->write_callback != NULL) {
                    void *args = ev->wcb_args;
                    ev->write_callback(this, _fired_evs[i].data.fd, args);
                }
                else {
                    //删除
                    fprintf(stderr, "fd %d get error, delete it from epoll\n", _fired_evs[i].data.fd);
                    this->del_io_event(_fired_evs[i].data.fd);
                }
            }

        }
    }
}

05 Lars-有关fd泄露的调试办法

/*
 * 这里我们处理的事件机制是
 * 如果EPOLLIN 在mask中, EPOLLOUT就不允许在mask中
 * 如果EPOLLOUT 在mask中, EPOLLIN就不允许在mask中
 * 如果想注册EPOLLIN|EPOLLOUT的事件, 那么就调用add_io_event() 方法两次来注册。
 * */

//添加一个io事件到loop中
void event_loop::add_io_event(int fd, io_callback *proc, int mask, void *args)
{
    int final_mask;
    int op;

    //1 找到当前fd是否已经有事件
    io_event_map_it it = _io_evs.find(fd);
    if (it == _io_evs.end()) {
        //2 如果没有操作动作就是ADD
        //没有找到
        final_mask = mask;    
        op = EPOLL_CTL_ADD;
    }
    else {
        //3 如果有操作董酒是MOD
        //添加事件标识位
        final_mask = it->second.mask | mask;
        op = EPOLL_CTL_MOD;
    }

    //4 注册回调函数
    if (mask & EPOLLIN) {
        //读事件回调函数注册
        _io_evs[fd].read_callback = proc;
        _io_evs[fd].rcb_args = args;
    }
    else if (mask & EPOLLOUT) {
        _io_evs[fd].write_callback = proc;
        _io_evs[fd].wcb_args = args;
    }
    
    //5 epoll_ctl添加到epoll堆里
    _io_evs[fd].mask = final_mask;
    //创建原生epoll事件
    struct epoll_event event;
    event.events = final_mask;
    event.data.fd = fd;
    if (epoll_ctl(_epfd, op, fd, &event) == -1) {
        fprintf(stderr, "epoll ctl %d error\n", fd);
        return;
    }

    //6 将fd添加到监听集合中
    listen_fds.insert(fd);
}

06 Lars-qps性能测试

//删除一个io事件从loop中
void event_loop::del_io_event(int fd)
{
    //将事件从_io_evs删除
    _io_evs.erase(fd);

    //将fd从监听集合中删除
    listen_fds.erase(fd);

    //将fd从epoll堆删除
    epoll_ctl(_epfd, EPOLL_CTL_DEL, fd, NULL);
}

//删除一个io事件的EPOLLIN/EPOLLOUT
void event_loop::del_io_event(int fd, int mask)
{
    //如果没有该事件,直接返回
    io_event_map_it it = _io_evs.find(fd);
    if (it == _io_evs.end()) {
        return ;
    }

    int &o_mask = it->second.mask;
    //修正mask
    o_mask = o_mask & (~mask);
    
    if (o_mask == 0) {
        //如果修正之后 mask为0,则删除
        this->del_io_event(fd);
    }
    else {
        //如果修正之后,mask非0,则修改
        struct epoll_event event;
        event.events = o_mask;
        event.data.fd = fd;
        epoll_ctl(_epfd, EPOLL_CTL_MOD, fd, &event);
    }
}
```

07 git企业开发基本流程

​    这里`del_io_event`提供两个重载,一个是直接删除事件,一个是修正事件。

### 4.3 Reactor集成event_loop机制

​        好了,那么接下来,就让让Lars Reactor框架集成`event_loop`机制。

首先简单修正一个`tcp_server.cpp`文件,对之前的`do_accept()`的调度时机做一下修正。

    1. 在`tcp_server`成员新增`event_loop`成员。

> lars_reactor/include/tcp_server.h

```h
#pragma once

#include <netinet/in.h>
#include "event_loop.h"


class tcp_server

public: 
    //server的构造函数
    tcp_server(event_loop* loop, const char *ip, uint16_t port); 

    //开始提供创建链接服务
    void do_accept();

    //链接对象释放的析构
    ~tcp_server();

private: 
    int _sockfd; //套接字
    struct sockaddr_in _connaddr; //客户端链接地址
    socklen_t _addrlen; //客户端链接地址长度

      // ============= 新增 ======================
    //event_loop epoll事件机制
    event_loop* _loop;
      // ============= 新增 ======================
}; 
```

相关文章:

C++负载均衡远程调用学习之集成测试与自动启动脚本

目录 01 Lars-LbAgentV0.7-route_lb获取路由全部主机信息 02 Lars-LbAgentV0.7-API模块注册功能实现和测试工 03 Lars-LbAgentV0.7-项目构建工具 04 Lars-LbAgentV0.7-启动工具脚本实现 05 Lars-有关fd泄露的调试办法 06 Lars-qps性能测试 07 git企业开发基本流程 01 Lar…...

双ISP(双互联网服务提供商)

目录 核心作用 适用场景 实现方式 优缺点 假设一家外贸公司 双ISP&#xff08;双互联网服务提供商&#xff09; 是指用户同时接入两个不同的网络服务提供商&#xff08;Internet Service Provider&#xff09;&#xff0c;通过冗余设计或负载均衡技术&#xff0c;提升网络…...

网工实验——静态路由与BFD联动

网络拓扑图 实验目的&#xff1a; PC与Server通信的时候主要走上面&#xff0c;当主用电路失效的时候走下面 设备&#xff1a; 一台PC主机 一台Server服务器 两台Router路由器 一台S3700交换机 配置 1.配置PC和Server的IP地址 PC Server 2.配置路由器 R3配置对应接口…...

谷歌在即将举行的I/O大会之前,意外泄露了其全新设计语言“Material 3 Expressive”的细节

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗&#xff1f;订阅我们的简报&#xff0c;深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同&#xff0c;从行业内部的深度分析和实用指南中受益。不要错过这个机会&#xff0c;成为AI领…...

【网络原理】IP协议

目录 ​编辑 一. IP协议的作用 二. IP协议报头 三. 拆包和组包 四. 地址管理 1&#xff09;动态分配IP地址 2&#xff09;NAT机制&#xff08;网络地址映射&#xff09; 3&#xff09; IPV6 五. IP转换 1&#xff09;客户端到服务器 2&#xff09;服务器到客户端 六…...

【Python 文件I/O】

Python 的文件 I/O 操作是数据处理的基础技能&#xff0c;涉及文件的读写、路径管理、异常处理等核心功能。以下是文件 I/O 的核心知识点&#xff1a; 一、基础文件操作 1. 打开文件 # 通用模式&#xff1a;r(读)/w(写)/a(追加) b(二进制)/t(文本&#xff0c;默认) f open(…...

torchrun单机多卡运行

torchrun命令使用 torchrun示例 export CUDA_VISIBLE_DEVICES0,1,2 nohup torchrun \--nproc_per_node3 \--nnodes1 \--node_rank0 \--master_addr"127.0.0.1" \--master_port1225 \/data/train.py \--batch_size 32 \--size 320运行如上sh命令发现&#xff0c;即 …...

数据管理平台是什么?企业应如何做好数据化管理?

目录 一、数据管理是什么&#xff1f; 二、数据管理平台有哪些作用&#xff1f; 1. 数据采集与整合 2. 数据清洗与预处理 3. 数据分析与挖掘 4. 数据共享与协作 三、企业应如何做好数据化管理&#xff1f; 1. 建立数据管理战略 2. 完善数据管理制度 3. 培养数据管理人…...

GuassDB如何创建兼容MySQL语法的数据库

GaussDB简介 GaussDB是由华为推出的一款全面支持OLTP和OLAP的分布式关系型数据库管理系统。它采用了分布式架构和高可靠性设计&#xff0c;可以满足大规模数据存储和处理的需求。GaussDB具有高性能、高可靠性和可扩展性等特点&#xff0c;适用于各种复杂的业务场景&#xff0c…...

Qt国际化实战--精通Qt Linguist工具链

概述 在全球化的今天,软件产品需要支持多种语言和地区,以满足来自世界各地用户的需求。Qt框架提供了一套完整的工具集来帮助开发者实现应用程序的国际化(i18n)和本地化(l10n),其中最核心的就是Qt Linguist工具链 关于国际化与本地化 国际化(i18n): 指的是设计和开发…...

C++内联函数

总结&#xff1a;内联函数是把函数变成一个代码块直接塞入源程序中&#xff0c;省去了一些参数传递和栈操作&#xff08;省时间&#xff09;&#xff0c;但是同时又增加了代码的大小&#xff08;因为原本的函数只有会使用指针指向该函数&#xff0c;但是内联函数是直接塞入&…...

26届秋招收割offer指南

26届暑期实习已经陆续启动&#xff0c;这也意味着对于26届的同学们来说&#xff0c;“找工作”已经提上了日程。为了帮助大家更好地准备暑期实习和秋招&#xff0c;本期主要从时间线、学习路线、核心知识点及投递几方面给大家介绍&#xff0c;希望能为大家提供一些实用的建议和…...

Python之内省与反射应用

Python之内省与反射应用 Python作为一门动态语言&#xff0c;具备了强大的内省&#xff08;Introspection&#xff09;与反射&#xff08;Reflection&#xff09;机制。这两个概念在运行时查看对象的属性、类型、方法等信息&#xff0c;甚至可以动态调用方法或修改对象的属性。…...

第三章:langchain加载word文档构建RAG检索教程(基于FAISS库为例)

文章目录 前言一、载入文档&#xff08;word&#xff09;1、文档载入代码2、文档载入数据解读&#xff08;Docx2txtLoader方法&#xff09;输入数据输出文本内容 3、Docx2txtLoader底层代码文档读取解读Docx2txtLoader底层源码示例文档读取输出结果 二、文本分割1、文本分割代码…...

球速最快的是哪种球类运动·棒球1号位

在体育运动中&#xff0c;球速最快的项目与棒球结合来看&#xff0c;可以分两个角度解读&#xff1a; 一、球速最快的运动项目 羽毛球以426公里/小时&#xff08;吉尼斯纪录&#xff09;的杀球速度位列榜首&#xff0c;远超棒球投球速度。其极速源于&#xff1a; 羽毛球拍甜区…...

TVM中Python如何和C++联调?

1. 编译 Debug 版本 # 在项目根目录下创建构建目录&#xff08;若尚未创建&#xff09; mkdir -p build && cd build# 配置 Debug 构建 cmake -DCMAKE_BUILD_TYPEDebug ..# 编译&#xff08;根据 CPU 核心数调整 -j 参数&#xff09; make -j$(nproc)2. 获取 Python 进…...

从零实现基于Transformer的英译汉任务

1. model.py&#xff08;用的是上一篇文章的代码&#xff1a;从0搭建Transformer-CSDN博客&#xff09; import torch import torch.nn as nn import mathclass PositionalEncoding(nn.Module):def __init__ (self, d_model, dropout, max_len5000):super(PositionalEncoding,…...

在 PyTorch 中借助 GloVe 词嵌入完成情感分析

一. Glove 词嵌入原理 GloVe是一种学习词嵌入的方法&#xff0c;它希望拟合给定上下文单词i时单词j出现的次数。使用的误差函数为&#xff1a; 其中N是词汇表大小&#xff0c;是线性层参数&#xff0c; 是词嵌入。f(x)是权重项&#xff0c;用于平衡不同频率的单词对误差的影响…...

大数据应用开发和项目实战-电商双11美妆数据分析

数据初步了解 &#xff08;head出现&#xff0c;意味着只出现前5行&#xff0c;如果只出现后面几行就是tail&#xff09; info shape describe 数据清洗 重复值处理 这个重复值是否去掉要看实际情况&#xff0c;比如说&#xff1a;昨天卖了5瓶七喜&#xff0c;今天卖了5瓶七…...

web服务

一、nginx的安装与启用 nginx的安装 开源版本的Nginx官网&#xff1a;http://nginx.org Nginx在安装的过程中可以选择源码安装也可以选择使用软件包安装 源码安装下载相应的源码压缩包解压后编译完成安装 软件安装包可以使用rpm或者apt命令进行安装&#xff0c;也可以使用dnf…...

在Spring Boot 中如何配置MongoDB的副本集 (Replica Set) 或分片集群 (Sharded Cluster)?

在 Spring Boot 中配置 MongoDB 副本集 (Replica Set) 或分片集群 (Sharded Cluster) 非常相似&#xff0c;主要区别在于连接字符串 (URI) 中提供的主机列表和一些特定选项。 最常的方式是使用 spring.data.mongodb.uri 属性配置连接字符串。 1. 连接到 MongoDB 副本集 (Repl…...

Oracle中游标和集合的定义查询及取值

在 Oracle 存储过程中&#xff0c;使用游标处理自定义数据行类型时&#xff0c;可以通过 定义记录类型&#xff08;RECORD&#xff09; 和 游标&#xff08;CURSOR&#xff09; 结合实现。 1. 定义自定义记录类型 使用 TYPE … IS RECORD 定义自定义行数据类型&#xff1a; DE…...

Python企业级MySQL数据库开发实战指南

简介 Python与MySQL的完美结合是现代Web应用和数据分析系统的基石,能够创建高效稳定的企业级数据库解决方案。本文将从零开始,全面介绍如何使用Python连接MySQL数据库,设计健壮的表结构,实现CRUD操作,并掌握连接池管理、事务处理、批量操作和防止SQL注入等企业级开发核心…...

【LLM】Open WebUI 使用指南:详细图文教程

Open WebUI 是一个开源的、可扩展且用户友好的自托管 AI 平台,专为生成式人工智能模型交互而设计。 Open WebUI 旨在为用户提供一个简单易用、功能强大且高度定制化的界面,使其能够轻松与各种 AI 模型(如文本生成、图像生成、语音识别等)进行交互。 一、安装与初始化配置 扩…...

前端封装框架依赖管理全攻略:构建轻量可维护的私有框架

前端封装框架依赖管理全攻略&#xff1a;构建轻量可维护的私有框架 前言 在自研前端框架的开发中&#xff0c;依赖管理是决定框架可用性的关键因素。不合理的依赖设计会导致&#xff1a; 项目体积膨胀&#xff1a;重复依赖使最终打包体积增加30%版本地狱&#xff1a;不同项目…...

Listremove数据时报错:Caused by: java.lang.UnsupportedOperationException

看了二哥的foreach陷阱后&#xff0c;自己也遇见了需要循环删除元素的情况&#xff0c;立马想到了当时自己阴差阳错的避开所有坑的解决方式&#xff1a;先倒序遍历&#xff0c;再删除。之前好使&#xff0c;但是这次不好使了&#xff0c;报错Caused by: java.lang.UnsupportedO…...

互联网大厂Java求职面试:云原生与AI融合下的系统设计挑战-1

互联网大厂Java求职面试&#xff1a;云原生与AI融合下的系统设计挑战-1 在当今云计算和人工智能迅猛发展的背景下&#xff0c;互联网大厂对Java工程师的要求已从传统的单体架构和业务逻辑处理&#xff0c;转向了更复杂的云原生架构设计、AI模型集成以及高并发系统的性能优化能…...

并发设计模式实战系列(16):屏障(Barrier)

&#x1f31f; 大家好&#xff0c;我是摘星&#xff01; &#x1f31f; 今天为大家带来的是并发设计模式实战系列&#xff0c;第十六章屏障&#xff08;Barrier&#xff09;&#xff0c;废话不多说直接开始~ 目录 一、核心原理深度拆解 1. 屏障的同步机制 2. 关键参数 二…...

pywinauto通过图片定位怎么更加精准的识别图片?

pywinauto通过图片定位怎么更加精准的识别图片&#xff1f; 可以使用置信度的配置&#xff0c;添加了对比图片相似程度达到多少就可以认为是合适的定位图片 import time from time import sleep from pywinauto.application import Application from pywinauto.keyboard impo…...

Spring Cloud Stream集成RocketMQ(kafka/rabbitMQ通用)

什么是Spring Cloud Stream Spring Cloud Stream 是 Spring 生态系统中的一个框架&#xff0c;用于简化构建消息驱动微服务的开发和集成。它通过抽象化的方式将消息中间件&#xff08;如 RabbitMQ、Kafka、RocketMQ 等&#xff09;的复杂通信逻辑封装成简单的编程模型&#xf…...

基于docker使用showdoc搭建API开发文档服务器

以下是基于 Docker 快速搭建 ShowDoc API 文档服务器的完整指南&#xff0c;包含优化配置和常见问题解决方案&#xff1a; 1. 快速部署方案 # 创建数据目录&#xff08;确保权限&#xff09; mkdir -p /showdoc_data/html && chmod 777 -R /showdoc_data# 一键启动容器…...

Vision-Language Models (VLMs) 视觉语言模型的技术背景、应用场景和商业前景(Grok3 DeepSearch模式回答)

prompt: 你是一位文笔精湛、十分专业的技术博客作者&#xff0c;你将从技术背景、应用场景和商业前景等多个维度去向读者介绍Vision-Language Models 关键要点 研究表明&#xff0c;视觉语言模型&#xff08;VLMs&#xff09;是多模态AI系统&#xff0c;能同时处理视觉和文本数…...

OpenAI大变革!继续与微软等,以非营利模式冲击AGI

今天凌晨2点&#xff0c;OpenAI宣布&#xff0c;将继续由非营利组织控制&#xff1b;现有的营利性实体将转变为一家公共利益公司&#xff1b;非营利组织将控制该公共利益公司&#xff0c;并成为其重要的持股方。 这也就是说OpenAI曾在去年提到的由非营利性转变成营利性公司&am…...

Ubuntu打开中文文本乱码

文章目录 中文乱码问题修复乱码系统字符编码修改文本编码修改vim乱码 utf-8编码原理特点应用场景与其他编码的转换 iso-8859-1基本信息字符涵盖应用场景与其他编码的关系 ubuntu打开文本出现乱码&#xff0c;可能是编码没设置对。 中文乱码问题 使用vim打开文本&#xff0c;或…...

车载通信网络安全:挑战与解决方案

1. 简介 当今时代见证了车载汽车技术的巨大发展&#xff0c;因为现代智能汽车可以被视为具有出色外部基础设施连接能力的信息物理系统 [ 1 ]。车载技术支持的现代智能汽车不应被视为类似于机械系统&#xff0c;而是由数百万行复杂代码组成的集成架构&#xff0c;可为车内乘客提…...

【Linux系统】读写锁

读者写者问题 重点 读者写者问题是并发编程中的经典问题&#xff0c;主要研究多个进程或线程对共享数据进行读和写操作时如何实现同步和互斥&#xff0c;以保证数据的一致性和操作的正确性 。 问题核心要点 同步与互斥&#xff1a;需要确保多个读者可以同时读共享数据&#…...

springBoot中自定义一个validation注解,实现指定枚举值校验

缘由 在后台写接口的时候&#xff0c;经常会出现dto某个属性是映射到一个枚举的情况。有时候还会出现只能映射到枚举类中部分枚举值的情况。以前都是在service里面自行判断&#xff0c;很多地方代码冗余&#xff0c;所以就想着弄一个自定义的validation注解来实现。 例如下面某…...

【Python】--装饰器

装饰器&#xff08;Decorator&#xff09;本质上是一个返回函数的函数 主要作用是&#xff1a;在不修改原函数代码的前提下&#xff0c;给函数增加额外的功能 比如&#xff1a;增加业务&#xff0c;日志记录、权限验证、执行时间统计、缓存等场景 my_decorator def func():pas…...

排序算法——堆排序

一、介绍 「堆排序heapsort」是一种基于堆数据结构实现的高效排序算法。我们可以利用已经学过的“建堆操作”和“元素出堆操作”实现堆排序。 1. 输入数组并建立小顶堆&#xff0c;此时最小元素位于堆顶。 2. 不断执行出堆操作&#xff0c;依次记录出堆元素&#xff0c;即可得…...

Day111 | 灵神 | 二叉树 | 验证二叉搜索树

Day111 | 灵神 | 二叉树 | 验证二叉搜索树 98.验证二叉搜索树 98. 验证二叉搜索树 - 力扣&#xff08;LeetCode&#xff09; 方法一&#xff1a;前序遍历 递归函数传入合法的左右边界&#xff0c;只有当前结点是合法的边界&#xff0c;才是二叉搜索树&#xff0c;否则就返回…...

软考-软件设计师中级备考 13、刷题 数据结构

倒计时17天时间不多了&#xff0c;数据库、UML、等知识点有基础直接略过&#xff0c;法律全靠考前的一两天刷题&#xff0c;英语直接放弃。 一、数据结构&#xff1a;链表、栈、队列、数组、哈希表、树、图 1、关于链表操作&#xff0c;说法正确的是&#xff1a; A)新增一个头…...

【5G通信】天线调整

在天线工程中&#xff0c;机械下倾角、电子下倾角和数字下倾角是调整天线波束指向的不同技术手段&#xff0c;其核心区别在于实现方式和灵活性&#xff1a; 1. 机械下倾角&#xff08;Mechanical Downtilt&#xff09; 定义&#xff1a;通过物理调整天线的安装角度&#xff0c…...

Kafka的Log Compaction原理是什么?

Kafka的Log Compaction&#xff08;日志压缩&#xff09;是一种独特的数据保留策略&#xff0c;其核心原理是保留每个key的最新有效记录。以下是关键原理分点说明&#xff1a; 1. 键值保留机制 通过扫描所有消息的key&#xff0c;仅保留每个key对应的最新value值。例如&#…...

嵌入式面试八股文(十四)·内存管理机制、优先级继承机制以及优先级翻转

目录 1. 内存管理算法&#xff08;五种内存管理机制&#xff09; 1.1 heap_1.c 1.2 heap_2.c 1.3 heap_3.c 1.4 heap_4.c 1.5 heap_5.c 1.6 总结 2. STM32通知寄存器有哪些&#xff1f; 2.1 核心寄存器组&#xff08;Cortex-M&#xff09; 2.2 特殊功能寄存…...

深度剖析:可视化如何重塑驾驶舱信息交互模式

为什么你开车时总觉得“信息太多却抓不住重点”&#xff1f; 今天的汽车早已不是单纯的交通工具&#xff0c;而是一个高度集成的信息终端。从导航、油耗、胎压到自动驾驶提示&#xff0c;各种数据不断涌进驾驶舱。 但问题也随之而来&#xff1a; 关键信息被淹没在一堆图标里…...

app根据蓝牙名字不同,匹配不同的产品型号,显示对应的UI界面

在开发一个 App 时&#xff0c;如果希望根据蓝牙设备名称&#xff08;Bluetooth Name&#xff09;的不同&#xff0c;自动匹配不同的产品型号&#xff0c;并显示对应的 UI 界面&#xff0c;可以按照以下思路来实现&#xff1a; ✅ 功能目标 扫描并连接蓝牙设备&#xff1b;获取…...

数据结构 --- 栈

1.栈的初始化 2.入栈 3.出栈 4.取出栈顶元素 5.获取栈中有效元素个数 6.栈的销毁 栈&#xff1a;⼀种特殊的线性表&#xff0c;其只允许在固定的⼀端进⾏插⼊和删除元素操作。进⾏数据插⼊和删除操作 的⼀端称为栈顶&#xff0c;另⼀端称为栈底。栈中的数据元素遵守后进先…...

37-算法打卡-栈与队列-滑动窗口最大值-leetcode(239)-第三十七天

1 题目地址 239. 滑动窗口最大值 - 力扣&#xff08;LeetCode&#xff09;239. 滑动窗口最大值 - 给你一个整数数组 nums&#xff0c;有一个大小为 k 的滑动窗口从数组的最左侧移动到数组的最右侧。你只可以看到在滑动窗口内的 k 个数字。滑动窗口每次只向右移动一位。返回 滑…...

【原创分享】魔音变声器内含超多语音包实时变声

魔音变声器,一款专业的调音变声器软件 亲测可使用所有功能[真棒] 去除所有广告 ————————————【下 载 地 址】———————————— 【​获取方法1】&#xff1a;https://pan.xunlei.com/s/VOP_TXtKNlevTgYvIlxmmJquA1?pwd8vpi# ————————————【下 …...

数据结构(一)——线性表的顺序表示和实现

一、线性表的定义 由n(n>0)个数据特性相同的元素构成的有限序列称为线性表&#xff0c;(n0)的时候被称为空表。 一个数据元素可以是简单的一个数据&#xff0c;一个符号&#xff0c;也可以是复杂的若干个数据项的组合。 二、线性表的类型定义 s线性表是由n(n≥0)个相同类…...