【C语言】Infiniband驱动mlx4_reset

一、注释

这个 mlx4_reset 函数负责重置 Mellanox 设备。它保存了设备的 PCI 头信息,然后重置了设备,之后还原保存的 PCI 头信息。请注意,该函数是用英文注释的,下面提供中文注释的版本。以下是该函数的流程:
1. 为保存 PCI 头信息分配内存。
2. 如果存在 PCI Express 能力结构,则保存 PCI 头信息。
3. 映射硬件重置寄存器地址空间。
4. 获取硬件信号量以防止闪存更新期间冲突。
5. 实际执行硬件重置操作。
6. 等待一段时间以确保设备重置完成。
7. 检查设备是否恢复到操作状态。
8. 如果设备已经恢复操作状态,则还原 PCI 头信息。
9. 清理和释放所有分配的资源。
以下是注释翻译成中文后的代码片段:

int mlx4_reset(struct mlx4_dev *dev) {
    // ...之前的代码略...

    /* 实际执行硬件重置 */
    writel(MLX4_RESET_VALUE, reset + MLX4_RESET_OFFSET);
    iounmap(reset);

    /* 文档称重置后应等待一秒钟才能访问设备 */
    msleep(1000);

    // ...之后的代码略...

    /* 现在恢复 PCI 头信息 */
    if (pcie_cap) {
        // 恢复 PCI Express Device Control 寄存器
        devctl = hca_header[(pcie_cap + PCI_EXP_DEVCTL) / 4];
        if (pcie_capability_write_word(dev->persist->pdev,
                                       PCI_EXP_DEVCTL,
                                       devctl)) {
            err = -ENODEV;
            mlx4_err(dev, "无法恢复 HCA PCI Express 设备控制寄存器,中止操作\n");
            goto out;
        }
        // 恢复 PCI Express Link Control 寄存器
        linkctl = hca_header[(pcie_cap + PCI_EXP_LNKCTL) / 4];
        if (pcie_capability_write_word(dev->persist->pdev,
                                       PCI_EXP_LNKCTL,
                                       linkctl)) {
            err = -ENODEV;
            mlx4_err(dev, "无法恢复 HCA PCI Express 链接控制寄存器,中止操作\n");
            goto out;
        }
    }

    // ...之后的清理代码略...

    return err;
}

请注意,这些注释更确切地描述了代码中的每个重要步骤,并对原开发者的注释进行翻译以更好地帮助中文读者理解代码。在 Linux 内核代码中,通常不鼓励添加太多注释,而是倾向于通过代码清晰表达意图。不过,如果在维护的项目中需要用中文注释,可以按照实际情况将代码中的关键部分翻译成中文。

注释,对关键代码部分进行解释:

#include <linux/errno.h>  // 包含Linux内核的错误号定义
#include <linux/pci.h>    // 包含用于PCI操作的函数和宏定义
#include <linux/delay.h>  // 包含延时函数
#include <linux/slab.h>   // 包含内存分配函数
#include <linux/jiffies.h>// 包含时间管理函数和宏

#include "mlx4.h" // 包含mlx4驱动的定义和声明

// 定义重置操作需要用到的常量
#define MLX4_RESET_BASE             0xf0000
#define MLX4_RESET_SIZE             0x400
#define MLX4_SEM_OFFSET             0x3fc
#define MLX4_RESET_OFFSET           0x10
#define MLX4_RESET_VALUE            swab32(1)

#define MLX4_SEM_TIMEOUT_JIFFIES    (10 * HZ)
#define MLX4_RESET_TIMEOUT_JIFFIES  (2 * HZ)

int mlx4_reset(struct mlx4_dev *dev)
{
    // 变量定义
    void __iomem *reset;     // 映射重置寄存器的地址
    u32 *hca_header = NULL;  // 存储设备PCI头信息的缓冲区
    int pcie_cap;
    u16 devctl, linkctl, vendor;
    unsigned long end;
    u32 sem;
    int i;
    int err = 0;
    // 以下是函数主要逻辑
    // 动态分配256字节的内存用于存储PCI头信息
    hca_header = kmalloc(256, GFP_KERNEL); 
    if (!hca_header) {
        // 分配内存失败的错误处理
    }

    // 获取PCIe能力寄存器的偏移量
    pcie_cap = pci_pcie_cap(dev->persist->pdev);

    // 备份当前的PCI配置头信息,忽略有特殊含义的配置偏移22和23
    for (i = 0; i < 64; ++i) {
        if (i == 22 || i == 23)
            continue;
        // 读PCI配置头信息到 hca_header 中
    }

    // 映射设备的重置寄存器地址
    reset = ioremap(pci_resource_start(dev->persist->pdev, 0) + MLX4_RESET_BASE, MLX4_RESET_SIZE);

    if (!reset) {
        // 重置寄存器映射失败处理
    }

    // 获取硬件信号量以防止在设备复位期间进行闪存更新
    end = jiffies + MLX4_SEM_TIMEOUT_JIFFIES;
    do {
        sem = readl(reset + MLX4_SEM_OFFSET);
        if (!sem)
            break;

        msleep(1);
    } while (time_before(jiffies, end));

    // sem仍然有效,则获取信号量失败
    if (sem) {
        // 获取信号量失败的错误处理
    }

    // 实际执行重置操作
    writel(MLX4_RESET_VALUE, reset + MLX4_RESET_OFFSET);

    // 释放重置寄存器的映射
    iounmap(reset);

    // 根据文档,重置后需要等待一秒钟再访问设备
    msleep(1000);

    // 等待设备复位完成并确认PCI设备可被访问
    end = jiffies + MLX4_RESET_TIMEOUT_JIFFIES;
    do {
        // 检查PCI_VENDOR_ID是否有效,如果有效,则设备复位成功
    } while (time_before(jiffies, end));

    // 如果vendor无效,代表设备复位失败
    if (vendor == 0xffff) {
        // 设备复位失败的错误处理
    }

    // 恢复之前保存的PCI配置头信息
    if (pcie_cap) {
        // 恢复PCIe设备控制和链接控制寄存器
    }

    // 恢复其他PCI配置头信息
    for (i = 0; i < 16; ++i) {
        // 写回PCI配置信息
    }

    // 最后,确保PCI_COMMAND寄存器被正确恢复
    if (pci_write_config_dword(dev->persist->pdev, PCI_COMMAND, hca_header[PCI_COMMAND / 4])) {
        // PCI_COMMAND寄存器恢复失败的错误处理
    }

out:
    // 释放之前分配的内存
    kfree(hca_header);

    return err;
}

这段代码涉及到硬件层面的操作,这其中包括了对PCI设备的配置空间的保存、设备重置以及恢复的过程。遵循Linux内核中的错误处理机制,使用goto语句跳转到错误处理代码段。通过互斥机制和延时确保操作的安全性。大部分详细的注释已经涵盖在代码里。

完整注释:

这段代码相对较长,将注释分成几部分进行讲解,每部分涵盖一个逻辑模块。

请注意:由于代码中使用了很多Linux内核特定的函数和宏定义,某些注释可能需要一定的内核知识才能完全理解。

//drivers\net\ethernet\mellanox\mlx4\reset.c
/*
 * 版权所有 (c) 2006, 2007 Cisco Systems, Inc. 保留所有权利。
 * 版权所有 (c) 2007, 2008 Mellanox Technologies. 保留所有权利。
 *
 * 这款软件可以在两种许可下的任何一种下提供给您。
 * 您可以选择被GNU通用公共许可证(GPL)版本2的条款所许可,
 * 可从该源代码树主目录中的COPYING文件中获取,
 * 或者选择下面的OpenIB.org BSD许可证:
 *
 *     源代码和二进制形式的再分发和使用是允许的,
 *     无论是否进行了修改,只要满足以下条件:
 *
 *      - 源代码的再分发必须保留上述版权声明、此条件列表和下面的免责声明。
 *
 *      - 以二进制形式进行的再分发必须在分发的文件和/或材料中复制上述版权声明、
 *        此条件列表以及随附的文件和/或材料中的免责声明。
 *
 * 本软件是按“原样”提供的,没有任何形式的保证,
 * 无论是明示的或暗示的,包括但不限于适销性、
 * 适用于特定用途的保证和非侵权。在任何情况下,
 * 作者或版权所有者均不对任何索赔、损害或其他责任承担责任,
 * 无论是在合同诉讼、侵权行为或其他方面,
 * 与本软件或本软件的使用或其他交易有关。
 */
// 引入一些必要的头文件
#include <linux/errno.h>    // 错误码定义
#include <linux/pci.h>      // PCI总线相关函数和结构体
#include <linux/delay.h>    // 延时相关的函数
#include <linux/slab.h>     // 内核内存分配相关
#include <linux/jiffies.h>  // 内核时间管理相关
#include "mlx4.h"           // Mellanox设备相关头文件
// 定义一个重置函数
int mlx4_reset(struct mlx4_dev *dev)
{
    void __iomem *reset;           // 映射设备寄存器的指针
    u32 *hca_header = NULL;        // 指向保存PCI头部数据的内存
    int pcie_cap;                  // PCI-E能力寄存器的位置
    u16 devctl, linkctl, vendor;   // 枚举一些PCI相关的变量
    unsigned long end;             // 用于记录超时时间
    u32 sem;                       // 记录半导体值
    int i;                         // 循环计数器
    int err = 0;                   // 错误码
    // 定义重置相关的常量
#define MLX4_RESET_BASE        0xf0000               // 重置寄存器的基础地址
#define MLX4_RESET_SIZE        0x400                 // 重置寄存器的大小
#define MLX4_SEM_OFFSET        0x3fc                 // 硬件信号量的偏移量
#define MLX4_RESET_OFFSET    0x10                  // 重置命令的偏移量
#define MLX4_RESET_VALUE    swab32(1)             // 重置命令的值
    // 定义超时的常数
#define MLX4_SEM_TIMEOUT_JIFFIES    (10 * HZ)  // 获取硬件信号量的超时时长
#define MLX4_RESET_TIMEOUT_JIFFIES    (2 * HZ)   // 重置等待超时的时长
    /*
     * 重置芯片。这个过程有点不优雅,因为我们必须在重置之前保存PCI头部,
     * 然后在芯片重启后恢复它。我们跳过配置空间偏移量22和23,因为它们有特殊含义。
     */
    // 是否需要保存完整的4K PCIe头?先分配空间以保存头部信息。
    hca_header = kmalloc(256, GFP_KERNEL);
    if (!hca_header) {
        err = -ENOMEM;  // 内存分配失败设置错误码
        mlx4_err(dev, "Couldn't allocate memory to save HCA PCI header, aborting\n");
        goto out;       // 跳转到函数的结束部分
    }
    // 获取PCI-E Capability的偏移量。
    pcie_cap = pci_pcie_cap(dev->persist->pdev);
    // 保存PCI配置空间的前256字节,跳过22和23偏移量的保存。
    for (i = 0; i < 64; ++i) {
        if (i == 22 || i == 23) 
            continue;
        // 读取PCI配置空间的每一个DWORD,并保存起来
        if (pci_read_config_dword(dev->persist->pdev, i * 4, hca_header + i)) {
            err = -ENODEV;  // 读取失败则设定错误码
            mlx4_err(dev, "Couldn't save HCA PCI header, aborting\n");
            goto out;
        }
    }

    // 映射重置寄存器的物理地址到虚拟地址空间
    reset = ioremap(pci_resource_start(dev->persist->pdev, 0) + MLX4_RESET_BASE, MLX4_RESET_SIZE);
    if (!reset) {
        err = -ENOMEM;  // 映射失败设置错误码
        mlx4_err(dev, "Couldn't map HCA reset register, aborting\n");
        goto out;
    }

    // 锁定硬件信号量,以阻止闪存更新
    end = jiffies + MLX4_SEM_TIMEOUT_JIFFIES;
    do {
        sem = readl(reset + MLX4_SEM_OFFSET);
        if (!sem)
            break;

        msleep(1);
    } while (time_before(jiffies, end));

    if (sem) {
        mlx4_err(dev, "Failed to obtain HW semaphore, aborting\n");
        err = -EAGAIN;  // 获取信号量失败设置错误码
        iounmap(reset);
        goto out;
    }

    // 实际进行重置操作
    writel(MLX4_RESET_VALUE, reset + MLX4_RESET_OFFSET);
    iounmap(reset);  // 解除映射

    // 文档指出在设备访问前等待一秒钟
    msleep(1000);

    // 等待设备复位完毕
    end = jiffies + MLX4_RESET_TIMEOUT_JIFFIES;
    do {
        if (!pci_read_config_word(dev->persist->pdev, PCI_VENDOR_ID, &vendor) && vendor != 0xffff)
            break;

        msleep(1);
    } while (time_before(jiffies, end));

    if (vendor == 0xffff) {
        err = -ENODEV;  // 设备重置后未恢复,则设置错误码
        mlx4_err(dev, "PCI device did not come back after reset, aborting\n");
        goto out;
    }

    // 恢复PCI头部信息
    if (pcie_cap) {
        devctl = hca_header[(pcie_cap + PCI_EXP_DEVCTL) / 4];
        if (pcie_capability_write_word(dev->persist->pdev, PCI_EXP_DEVCTL, devctl)) {
            err = -ENODEV;  // 恢复失败则设置错误码
            mlx4_err(dev, "Couldn't restore HCA PCI Express Device Control register, aborting\n");
            goto out;
        }
        linkctl = hca_header[(pcie_cap + PCI_EXP_LNKCTL) / 4];
        if (pcie_capability_write_word(dev->persist->pdev, PCI_EXP_LNKCTL, linkctl)) {
            err = -ENODEV;  // 恢复失败则设置错误码
            mlx4_err(dev, "Couldn't restore HCA PCI Express Link control register, aborting\n");
            goto out;
        }
    }

    for (i = 0; i < 16; ++i) {
        if (i * 4 == PCI_COMMAND)
            continue;

        if (pci_write_config_dword(dev->persist->pdev, i * 4, hca_header[i])) {
            err = -ENODEV;  // 写入失败则设置错误码
            mlx4_err(dev, "Couldn't restore HCA reg %x, aborting\n", i);
            goto out;
        }
    }

继续从最后一个`for`循环。

    // 最后恢复PCI_COMMAND寄存器。
    if (pci_write_config_dword(dev->persist->pdev, PCI_COMMAND, hca_header[PCI_COMMAND / 4])) {
        err = -ENODEV;  // 写入失败则设置错误码
        mlx4_err(dev, "Couldn't restore HCA COMMAND, aborting\n");
        goto out;
    }

out:
    kfree(hca_header);  // 释放之前保存PCI头部信息的内存空间

    return err;  // 返回错误码,0代表成功,非0代表失败
}

这部分代码主要执行了芯片的重置过程,并且在重置前后操作了PCI头部信息的保存与恢复,以确保设备能够在重置之后正常工作。需要注意的是代码中充满了错误检查和处理的步骤,以保证万一出现不可预见的问题时能够安全退出,并且反馈给调用者相应的错误信息。

二、讲解

这段代码来自Linux内核的Mellanox网络驱动mlx4,位于文件`reset.c`中。这个文件负责处理`mlx4`设备的重置逻辑。以下是代码中各个部分的中文解释:
代码开始于一个版权声明,声明代码属于Cisco Systems, Inc. 和 Mellanox Technologies所有,许可证可选为GPL(GNU通用公共许可证)版本2或OpenIB.org的BSD(伯克利软件许可证)。
接着引入了一些所需的Linux内核头文件。这些文件允许代码访问一些内核提供的功能,如内存分配和时间相关功能。
声明了`mlx4_reset`函数,它负责重置`mlx4_dev`指向的设备。
在函数中,定义了一些宏和它们的值:这些宏用于方便地引用重置流程中所需要的一些硬件寄存器的偏移量和相关的值。
函数`mlx4_reset`的实现分几个步骤:
1. 保存PCI配置头信息:在重置设备之前,需要保存PCI配置头的内容,以便后面可以恢复它。这是因为重置操作会导致这些信息丢失。作者注意到需要略过配置空间偏移量22和23,因为它们有特殊含义。
2. 映射重置寄存器:代码通过`ioremap`函数映射了设备的重置寄存器区域到内核地址空间,以便可以对它们进行读写操作。
3. 获取硬件信号量:在重置前需要获得一个硬件信号量,防止在重置时对闪存发生写操作。这里使用了循环,并通过读取信号量寄存器来判断是否获取成功。
4. 执行重置:通过向某个特定的寄存器写入特定值来触发硬件重置。
5. 等待设备初始化:硬件文档建议在访问设备之前等待一秒钟。
6. 恢复PCI头信息:重置完成后,PCI配置头信息需要从之前保存的内容恢复。
7. 清理:释放分配的内存空间,并返回执行结果。
整个函数的逻辑层次清晰,分为了准备、执行和清理三个主要部分。出错处理(错误标记`err`)也涵盖了各种可能的失败情况,例如内存分配失败、映射失败、信号量获取失败等,并在最后正确地释放资源和返回相应的错误代码。

ChatGPT

mlx4_reset是一种在InfiniBand驱动中遇到的函数,它一般是Mellanox InfiniBand驱动的一部分。这个函数用来将Mellanox InfiniBand硬件设备恢复到其初始状态。在Linux内核中,Mellanox的mlx4驱动负责管理InfiniBand设备。这个驱动通常与某些InfiniBand芯片组一起使用,比如那些被用在高性能计算集群中的芯片组。
由于InfiniBand驱动的代码是专业领域的内容,且通常需要深入了解硬件规格和内核编程,一个典型的`mlx4_reset`函数可能涉及复杂的硬件操作,包括直接与硬件交互的函数调用,内核同步机制,可能还有对硬件寄存器的读写。
在具体的C代码层面上,`mlx4_reset`函数的实现依赖于Mellanox硬件和驱动的具体版本,因此会根据不同的设备模型和驱动版本有所差异。但是,其大致框架可能如下所示:

int mlx4_reset(struct mlx4_dev *dev)
{
    // 获取设备上下文或设备特定的数据结构的引用
    struct mlx4_priv *priv = mlx4_priv(dev);

    // 执行硬件复位序列,可能包括:
    // - 禁用中断
    // - 停止设备端口
    // - 重置设备的某些区域或寄存器
    // - 将硬件状态置为已知的初始状态

    /* 示例代码,非真实代码 */
    mlx4_disable_interrupts(dev);
    mlx4_stop_device_ports(dev);
    
    // 实际的重置操作可以涉及对硬件寄存器的操作
    writel(value, priv->reset_reg); // 写入复位寄存器以重置设备

    // 检查设备是否已经重置完毕并且准备好重新初始化
    if (!mlx4_device_ready(dev)) {
        // 如果设备未能恢复到初始状态,则返回错误
        return -EIO;
    }

    // 重置成功后的操作,可能会重新初始化设备
    // 硬件复位后的设备必须重新初始化以便再次使用
    mlx4_enable_interrupts(dev);
    mlx4_start_device(dev);

    // 复位成功,返回0表示成功
    return 0;
}

请注意,上面的代码只是一个示意性的伪代码。实际的`mlx4_reset`函数包含更详细的步骤,包括对硬件规格的复杂操作,错误处理和设备状态的检查。要获得真实的源代码,您很可能需要访问Linux内核的源代码,具体到drivers/net/ethernet/mellanox/mlx4/目录中,您可以在该目录下找到与mlx4相关的实现。

通义灵码

在InfiniBand驱动程序中,mlx4_reset 函数通常用于复位 Mellanox InfiniBand Host Channel Adapter (HCA) 的硬件状态或某个特定功能模块。这个函数的作用是在遇到硬件错误、超时或其他需要恢复正常操作状态的情况时,重新初始化和同步HCA的硬件资源。

在C语言实现的Mellanox mlx4系列驱动中,mlx4_reset 函数可能执行如下步骤:

  1. 停止活动

    • 暂停所有正在进行的传输操作,包括清理发送和接收队列中的未完成请求(Work Requests, WRs)。
    • 中断任何正在使用的DMA传输。
  2. 硬件复位

    • 向HCA发送复位命令,使其进入已知初始状态。
    • 根据硬件规格书,通过相应的寄存器操作来触发和监控复位过程。
  3. 资源重置

    • 释放之前分配的硬件资源,如队列对、内存窗口、保护域等。
    • 重新初始化这些资源,确保它们处于有效可用的状态。
  4. 重新配置

    • 在硬件复位完成后,根据设备配置重新设置寄存器值和内部参数。
    • 重新建立硬件队列、中断处理机制和其他关键的硬件上下文。
  5. 启动服务

    • 重新启动必要的服务,比如恢复中断服务例程(Interrupt Service Routines, ISRs)。
    • 通知上层协议栈和应用程序复位已完成,可以继续进行新的通信操作。

请注意,上述流程是基于一般理解推测出的,具体实现细节会因不同版本的mlx4驱动而异,查看源代码是最准确的理解方式。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/503396.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

springboot项目学习-瑞吉外卖(4)续

1.任务 菜品的添加功能(涉及到两张表的数据添加) 2.菜品添加 功能页面如上&#xff0c;该页面有两个注意点 菜品分类&#xff1a;点击菜品分类后&#xff0c;会展示当前已有菜品&#xff1a;这个功能的实现要从category表里查询数据&#xff0c;然后再做展示口味做法配置&#…

SRS OBS利用RTMP协议实现音视频推拉流

参考&#xff1a;https://ossrs.net/lts/zh-cn/docs/v5/doc/getting-started 1&#xff09;docker直接运行SRS服务&#xff1a; docker run --rm -it -p 1935:1935 -p 1985:1985 -p 8080:8080 registry.cn-hangzhou.aliyuncs.com/ossrs/srs:5运行起来后可以http://localho…

java Web 疫苗预约管理系统用eclipse定制开发mysql数据库BS模式java编程jdbc

一、源码特点 JSP 疫苗预约管理系统是一套完善的web设计系统&#xff0c;对理解JSP java 编程开发语言有帮助&#xff0c;系统具有完整的源代码和数据库&#xff0c;系统主要采用B/S模式开发。开发环境为TOMCAT7.0,eclipse开发&#xff0c;数据库为Mysql5.0&#xff0c;使…

kaggle竞赛(房价预测)(Pytorch 06)

一 下载数据集 此数据集由Bart de Cock于2011年收集&#xff0c;涵盖了2006‐2010年期间 亚利桑那州 埃姆斯市的房价。 下载地址&#xff1a; import hashlib import os import tarfile import zipfile import requests#save DATA_HUB dict() DATA_URL http://d2l-data.s3…

“崖山数据库杯”深圳大学程序设计竞赛(正式赛)M题 一图秒

“崖山数据库杯”深圳大学程序设计竞赛&#xff08;正式赛&#xff09;_ACM/NOI/CSP/CCPC/ICPC算法编程高难度练习赛_牛客竞赛OJ (nowcoder.com) —————— 可以去牛客看题解&#xff1a; 题解 | #暂时没想法#_牛客博客 (nowcoder.net) —————— 上面的就是题解了。…

Adobe Illustrator 2023 for Mac/Win:创意无限,设计无界

在数字艺术与设计领域&#xff0c;Adobe Illustrator 2023无疑是一颗璀璨的明星。这款专为Mac和Windows用户打造的矢量图形设计软件&#xff0c;以其强大的功能和卓越的性能&#xff0c;赢得了全球设计师的广泛赞誉。 Adobe Illustrator 2023在继承前代版本优点的基础上&#…

基于ARM内核的智能手环(day1)

整体介绍 智能手环由 ARM 内核 MCU(Cortex-M 系列)、TFTLCD 屏、温湿度传感器、心率传感器、 加速度传感器等主要几部分构成。该平台硬件采用 STM32 芯片&#xff0c;通过对温湿度传感器的驱动编写&#xff0c;获取周围温湿度数据&#xff0c;并在 LCD 屏显示&#xff0c;通过对…

设计模式12--组合模式

定义 案例一 案例二 优缺点

docker配置github仓库ghcr国内镜像加速

文章目录 说明ghcr.io简介配置镜像命令地址命令行方式1panel面板方式方式一&#xff1a;配置镜像加速&#xff0c;命令行拉取方式二&#xff1a;配置镜像仓库&#xff0c;可视化拉取 说明 由于使用的容器需要从github下载镜像&#xff0c;服务器在国外下载速度很慢&#xff0c…

MySQL InnoDB 之 多版本并发控制(MVCC)

多版本并发控制&#xff08;MVCC&#xff0c;Multi-Version Concurrency Control&#xff09;是数据库管理系统中用于提供高并发性和在事务处理中实现隔离级别的一种技术。MVCC 允许系统在不完全锁定数据库资源的情况下&#xff0c;处理多个并发事务&#xff0c;从而提高了数据…

计算机网络实验五:特定主机路由和默认路由

实验五&#xff1a;特定主机路由和默认路由 5.1 实验目的 &#xff08;1&#xff09;学习默认路由的概念和作用 &#xff08;2&#xff09;学习特定路由的概念和作用 &#xff08;3&#xff09;了解网络中路由选择的基本原理和应用 5.2 实验步骤 5.2.1 构建网络拓扑 在栏…

LeetCode - 字母板上的路径

1138. 字母板上的路径 刚看到这道题的时候,我居然想用搜索去做这道题,其实有更优解,用 / %算会更加的快,只需要遍历一次即可.假如说我们要找n,n是第13个字母,那他就位于 13 / 5 2, 13 % 5 3.他就位于三行三列(a为0,0),知道了原理,代码就好写了. class Solution { public:st…

基于51单片机HC05蓝牙环境检测系统

目录 1、概要 2、HC05配对传送数据教程 2.1 进入AT模式 2.2串口软件配置 2.3 异常分析 3、代码编写 4、原理图 5、仿真图 6、实物运行视频 7、小结 资料下载地址&#xff1a;基于51单片机手自动浇花系统 1、概要 本文详细介绍HC05蓝牙模块与51单片机的连接配对过程&#xff0c…

【WEEK5】 【DAY5】DML语言【中文版】

2024.3.29 Friday 目录 3.DML语言3.1.外键&#xff08;了解&#xff09;3.1.1.概念3.1.2.作用3.1.3.添加&#xff08;书写&#xff09;外键的几种方法3.1.3.1.创建表时直接在主动引用的表里写&#xff08;被引用的表的被引用的部分&#xff09;3.1.3.2.先创建表后修改表以添加…

二十四种设计模式与六大设计原则(三):【装饰模式、迭代器模式、组合模式、观察者模式、责任链模式、访问者模式】的定义、举例说明、核心思想、适用场景和优缺点

接上次博客&#xff1a;二十四种设计模式与六大设计原则&#xff08;二&#xff09;&#xff1a;【门面模式、适配器模式、模板方法模式、建造者模式、桥梁模式、命令模式】的定义、举例说明、核心思想、适用场景和优缺点-CSDN博客 目录 装饰模式【Decorator Pattern】 定义…

设计模式(9):外观模式

一.迪米特法则(最少知识原则) 一个软件实体应当尽可能少的与其他实体发生相互作用。 二.外观模式 为子系统提供统一的入口&#xff0c;封装子系统的复杂性&#xff0c;便于客户端调用。它的核心是什么呢&#xff0c;就是为我们的子系统提供一个统一的入口&#xff0c;封装子…

IDE/VS2015和VS2017帮助文档MSDN安装和使用

文章目录 概述VS2015MSDN离线安装离线MSDN的下载离线MSDN安装 MSDN使用方法从VS内F1启动直接启动帮助程序跳转到了Qt的帮助网页 VS2017在线安装MSDN有些函数在本地MSDN没有帮助&#xff1f;切换中英文在线帮助文档 概述 本文主要介绍了VS集成开发环境中&#xff0c;帮助文档MS…

探索一致性哈希算法以及在 Dubbo 负载均衡中的应用

文章目录 负载均衡简介基于哈希算法的负载均衡策略传统哈希算法一致性哈希算法虚拟一致性哈希算法 一致性哈希在 Dubbo 中的应用ConsistentHashSelector 构造方法ConsistentHashSelector select方法 负载均衡简介 负载均衡&#xff08;Load Balance&#xff0c;简称 LB&#x…

国产AI大模型推荐(一)

文心一言 主要功能&#xff1a; 各种类型的问答、各种文本创作、推理与数学计算、写代码、聊天交流、图片生成等。 链接&#xff1a;文心一言 讯飞星火 特点&#xff1a; 内容生成能力&#xff1a;我可以进行多风格多任务长文本生成&#xff0c;例如邮件、文案、公文、作文、对…

汇总:五个开源的Three.js项目

Three.js 是一个基于 WebGL 的 JavaScript 库&#xff0c;它提供了一套易于使用的 API 用来在浏览器中创建和显示 3D 图形。通过抽象和简化 WebGL 的复杂性&#xff0c;Three.js 使开发者无需深入了解 WebGL 的详细技术就能够轻松构建和渲染3D场景、模型、动画、粒子系统等。 T…