MPI之组通信

news2024/11/18 7:37:21

在前面的文章中,对点对点通信API进行了介绍,本文将对MPI组通信相关API进行介绍

一对多

Broadcast

将一个进程的数据广播到所有其他进程中,函数原型:

int MPI_Bcast(void *buffer, int count, MPI_Datatype datatype, int root, MPI_Comm comm);

函数参数详解:

  • void *buffer:指向待广播的数据的起始地址。
  • int count:待广播数据的数量。
  • MPI_Datatype datatype:待广播数据的类型。
  • int root:广播数据的根进程号。
  • MPI_Comm comm:通信域。

使用时,需要指定进行分发数据的根进程号root,该进程的缓冲区中数据将会被复制到所有的当前通信域中的其他进程的缓冲区。
MPI_Bcast 本质上是点对点通信,只不过是一个进程重复的向其他不同进程发送数据的过程。

代码示例:

#include <mpi.h>
#include <stdio.h>

int main(int argc, char** argv) {
    int rank, size, root = 0;
    int data[4] = {1, 2, 3, 4};

    MPI_Init(&argc, &argv);
    MPI_Comm_rank(MPI_COMM_WORLD, &rank);
    MPI_Comm_size(MPI_COMM_WORLD, &size);

    if (rank == root) {
        // 广播数据
        MPI_Bcast(data, 4, MPI_INT, root, MPI_COMM_WORLD);
    } else {
        // 接收广播数据
        MPI_Bcast(data, 4, MPI_INT, root, MPI_COMM_WORLD);
    }

    // 输出每个进程接收到的数据
    printf("Process %d received data: %d %d %d %d\n", rank, data[0], data[1], data[2], data[3]);

    MPI_Finalize();
    return 0;
}

在这里插入图片描述

Scatter

将一个进程的数据分割成等量的部分,并将每个部分发送给多个其他进程,每个接收进程接收到完整数据的一部分等量的数据,函数原型:

int MPI_Scatter(void *sendbuf, int sendcount, 
MPI_Datatype sendtype, void *recvbuf, int recvcount, 
MPI_Datatype recvtype, int root, MPI_Comm comm);

函数参数含义:

  • void *sendbuf:指向待分发数据的起始地址。
  • int sendcount:每个分发数据缓冲区的大小。
  • MPI_Datatype sendtype:待分发数据缓冲区中数据的数据类型。
  • void *recvbuf:指向接收分发数据的缓冲区。
  • int recvcount:每个接收分发数据缓冲区的大小。
  • MPI_Datatype recvtype:接收分发数据缓冲区中数据的数据类型。
  • int root:分发数据的根进程号。
  • MPI_Comm comm:通信域。

同样的,MPI_Scatter 函数需要指定分发操作的根进程号 root,该进程的缓冲区中的数据将被分发到所有其他进程的缓冲区中。

代码示例:

#include <mpi.h>
#include <stdio.h>

int main(int argc, char** argv) {
    int rank, size;
    int data[8] = {1, 2, 3, 4, 5, 6, 7, 8};
    int subdata[2];

    MPI_Init(NULL, NULL);
    MPI_Comm_rank(MPI_COMM_WORLD, &rank);
    MPI_Comm_size(MPI_COMM_WORLD, &size);

    if (size != 4) {
        fprintf(stderr, "Number of processes must be 4 for this example\n");
        MPI_Abort(MPI_COMM_WORLD, 1);
    }

    MPI_Scatter(data, 2, MPI_INT, subdata, 2, MPI_INT, 0, MPI_COMM_WORLD);

    // 输出每个进程接收到的数据
    printf("Process %d received data: %d %d\n", rank, subdata[0], subdata[1]);
    MPI_Finalize();
    return 0;
}

数据分发过程:
在这里插入图片描述
从上图我们不难发现,使用MPI_Scatter发送数据,不仅会和通信域中的其他进程通信,还会给自身发送数据,将数据切割成等分量,依次发送给接收进程,接收进程收到的数据不一样。

多对一

Gather

是一种数据收集和汇总通信操作,该方法将多个进程中的数据收集到同一个进程中进行汇总。
前面讲到的一对多数据一个进程分撒消息,这里是汇总消息。

函数原型:

int MPI_Gather(const void* sendbuf, int sendcount, 
MPI_Datatype sendtype, void* recvbuf, 
int recvcount, MPI_Datatype recvtype, int root, MPI_Comm comm)

函数参数含义:

  • sendbuf:发送缓冲区指针
  • sendcount:发送数据个数
  • sendtype:发送数据类型
  • recvbuf:接收缓冲区指针
  • recvcount:每个进程接收的数据个数
  • recvtype:接收缓冲区的数据类型
  • root:目的进程的进程号
  • comm:通信域

该函数在root进程中创建一个大的接收缓冲区,从其他进程接收数据。每个进程可以通过指定发送缓冲区、发送数据个数和数据类型来向 root 进程发送数据。root 进程需要指定接收缓冲区、每个进程接收的数据个数和数据类型。由于在 MPI_Gather 操作中只有 root 进程需要接收数据,因此其他进程不需要指定 recvbuf 参数,当 MPI_Gather 函数被调用时,其他进程将等待其调用结束。当 MPI_Gather 函数完成时,root 进程将拥有一个大小为 recvcount * size 的接收缓冲区。

代码实例:

#include <mpi.h>
#include <stdio.h>

int main(int argc, char** argv) {
    int rank, size, root = 0;
    int data[2];
    int* recvdata = NULL;

    MPI_Init(&argc, &argv);
    MPI_Comm_rank(MPI_COMM_WORLD, &rank);
    MPI_Comm_size(MPI_COMM_WORLD, &size);

    // 为 root 进程分配一个大的接收缓冲区
    if (rank == root) {
        recvdata = new int[2 * size];
    }

    // 每个进程向 root 进程发送数据
    data[0] = rank * 2;
    data[1] = rank * 2 + 1;
    MPI_Gather(data, 2, MPI_INT, recvdata, 2, MPI_INT, root, MPI_COMM_WORLD);
    // 输出每个进程接收到的数据
    printf("Process %d received data: %d %d\n", rank, data[0], data[1]);

    // root 进程输出汇总后的数据
    if (rank == root) {
        printf("Root process received data:");
        for (int i = 0; i < 2 * size; i++) {
            printf(" %d", recvdata[i]);
        }
        printf("\n");
        delete[] recvdata;
    }

    MPI_Finalize();
    return 0;
}

在这里插入图片描述

多对多

Allgather

Allgather在所有进程之间进行全局数据通信,每个进程发送和接收数据,从而实现数据的交换和汇总。

函数原型:

int MPI_Allgather(const void* sendbuf, int sendcount, 
MPI_Datatype sendtype, void* recvbuf, int recvcount, 
MPI_Datatype recvtype, MPI_Comm comm)

函数参数详解:

  • sendbuf:发送缓冲区指针
  • sendcount:发送数据个数
  • sendtype:发送数据类型
  • recvbuf:接收缓冲区指针
  • recvcount:每个进程接收的数据个数
  • recvtype:接收缓冲区的数据类型
  • comm:通信域

与 MPI_Gather 函数类似,但在 MPI_Allgather 函数中,每个进程都将向所有其他进程发送数据,并从所有其他进程接收数据。因此,MPI_Allgather 可以实现任意进程之间的数据交换和汇总,而 MPI_Gather 只能实现一个进程向其他进程发送数据并在 root 进程中汇总数据的操作。

在这里插入图片描述
代码实例

#include <mpi.h>
#include <stdio.h>

int main(int argc, char** argv) {
    int rank, size;
    int senddata[2], recvdata[6];

    MPI_Init(&argc, &argv);
    MPI_Comm_rank(MPI_COMM_WORLD, &rank);
    MPI_Comm_size(MPI_COMM_WORLD, &size);

    // 设置发送的数据
    senddata[0] = rank * 2;
    senddata[1] = rank * 2 + 1;

    // 在所有进程之间进行全局数据通信
    MPI_Allgather(senddata, 2, MPI_INT, recvdata, 2, MPI_INT, MPI_COMM_WORLD);

    // 输出每个进程接收到的数据
    printf("Process %d received data:", rank);
    for (int i = 0; i < 6; i++) {
        printf(" %d", recvdata[i]);
    }
    printf("\n");

    MPI_Finalize();
    return 0;

Reduce 归约

所有进程向同一个进程发送消息,与前面讲到的Broadcast的发送方向相反。
接收进程对收到的所有消息进程归约处理;
常见归约操作:

  • MAX
  • MIN
  • SUM
  • PROD
  • LAND
  • BAND
  • LOR
  • BOR
  • LXOR
  • BXOR
  • MAXLOC
  • MINLOC

几个例子,五个进程拿五个不同的大数字,现在需要对这五个数据进行求和,那么就可以将数据发送给一个进程,操作为SUM。

函数原型:

int MPI_Reduce(const void* sendbuf, void* recvbuf, 
int count, MPI_Datatype datatype, MPI_Op op, int root, 
MPI_Comm comm)

函数参数详解:

  • sendbuf:发送缓冲区的首地址
  • recvbuf:用于接收归约结果的本地进程缓冲区的首地址
  • count:缓冲区中元素的数量
  • datatype:元素类型的 MPI 数据类型句柄
  • op:MPI_Op 类型的操作句柄,用作约减运算(如 MPI_SUM、MPI_MAX 等)
  • root:接收归约结果的进程号
  • comm:进程的 MPI 通信域,即进程所属的组

对于每个连续的缓冲区对,使用 op 句柄中定义的约减函数来将缓冲区中的值合并为一个值,并将结果存储在指定的接收缓冲区中。最终结果只会出现在进程 root 的缓冲区中。

代码实例:

#include <mpi>
#include <stdio.h>

int main(int argc, char** argv) {
    int rank, size, sum;
    MPI_Init(&argc, &argv);
    MPI_Comm_rank(MPI_COMM_WORLD, &rank);
    MPI_Comm_size(MPI_COMM_WORLD, &size);

    MPI_Reduce(&rank, &sum, 1, MPI_INT, MPI_SUM, 0, MPI_COMM_WORLD);
    if (rank == 0) {
        printf("Sum of all ranks = %d\n", sum);
    }

    MPI_Finalize();
    return 0;
}

在这里插入图片描述

Allreduce

与Reduce不同的是,Allreduce无root参数,所有进程都将获得结果,结果会通过广播的方式传播给其他进程。

函数原型:

int MPI_Allreduce(const void* sendbuf, void* recvbuf, 
int count, MPI_Datatype datatype, MPI_Op op, MPI_Comm comm)

函数参数:

  • sendbuf:发送缓冲区的首地址
  • recvbuf:用于接收归约结果的本地进程缓冲区的首地址
  • count:缓冲区中元素的数量
  • datatype:元素类型的 MPI 数据类型句柄
  • op:MPI_Op 类型的操作句柄,用作约减运算(如 MPI_SUM、MPI_MAX 等)
  • comm:进程的 MPI 通信域,即进程所属的组

函数通过将每个进程的本地发送缓冲区中的值与其他进程的相应值结合来计算一个约减的全局值,并将结果发送回本地接收缓冲区中。MPI_Allreduce 函数的本质是针对所有进程执行 MPI_Reduce 和 MPI_Bcast 操作的组合。

代码实例:

#include <mpi.h>
#include <stdio.h>

int main(int argc, char** argv) {
    int rank, size, sum;
    MPI_Init(&argc, &argv);
    MPI_Comm_rank(MPI_COMM_WORLD, &rank);
    MPI_Comm_size(MPI_COMM_WORLD, &size);

    MPI_Allreduce(&rank, &sum, 1, MPI_INT, MPI_SUM, MPI_COMM_WORLD);
    printf("Rank %d, Sum of all ranks = %d\n", rank, sum);

    MPI_Finalize();
    return 0;
}

在这里插入图片描述

Reduce scatter

MPI_Reduce_scatter 是 MPI 中的一个全局规约通信操作,其作用是将输入缓冲区中的数据进行约简,并将结果分发到多个进程中。MPI_Reduce_scatter 归约操作类似于 MPI_Reduce,但是它对约减结果进行分割并分发到所有进程中。MPI_Reduce_scatter 操作可用于各种规约操作,例如求和、求最大/最小值等。

函数原型:

int MPI_Reduce_scatter(const void *sendbuf, void *recvbuf, 
const int recvcounts[], MPI_Datatype datatype, 
MPI_Op op, MPI_Comm comm)

函数参数详解:

  • sendbuf:发送缓冲区的首地址
  • recvbuf:用于接收归约结果的本地进程缓冲区的首地址
  • recvcounts:一个数组,描述了每个进程期望接收的元素数量
  • datatype:元素类型的 MPI 数据类型句柄
  • op:MPI_Op 类型的操作句柄,用作约减运算(如 MPI_SUM、MPI_MAX 等)
  • comm:进程的 MPI 通信域,即进程所属的组

函数的作用是将输入缓冲区的数据约减,并按每个进程期望接收的元素数量将结果分发到每个进程中。MPI_Reduce_scatter 函数实际上将 MPI_Reduce 和 MPI_Scatter 功能组合成一个操作。MPI_Reduce_scatter中,每个进程都将输入数组的所有项进行约减操作,并使用 MPI_Scatter 函数将约减后的数据发送到所有进程中。MPI_Reduce_scatter 必须在所有进程中同时调用。

代码实例:

#include <mpi.h>
#include <stdio.h>
#include <stdlib.h>

int main(int argc, char** argv) {
    int rank, size, sum;
    int global_sum;
    MPI_Init(&argc, &argv);
    MPI_Comm_rank(MPI_COMM_WORLD, &rank);
    MPI_Comm_size(MPI_COMM_WORLD, &size);

    int *sendbuf = (int*)malloc(sizeof(int) * size);
    int *recvbuf = (int*)malloc(sizeof(int));

    for (int i = 0; i < size; i++) {
        sendbuf[i] = rank;
    }

    MPI_Reduce_scatter(sendbuf, recvbuf, &size, MPI_INT, MPI_SUM, MPI_COMM_WORLD);

    printf("Rank %d, Sum of all ranks = %d\n", rank, *recvbuf);

    free(sendbuf);
    free(recvbuf);
    MPI_Finalize();
    return 0;
}

在这里插入图片描述

Scan

每一个进程都对排在它前面的进程进行归约操作;
MPI_Scan调用的结果是,对于每一个进程i,对于进程0…i的发送缓冲区中的数据进行指定的归约操作,结果存放在进程i的接收缓冲区中。

函数原型:

int MPI_Scan(const void *sendbuf, void *recvbuf, 
int count, MPI_Datatype datatype, MPI_Op op, MPI_Comm comm)

函数参数详解:

  • sendbuf:发送缓冲区的首地址
  • recvbuf:用于接收归约结果的本地进程缓冲区的首地址
  • count:发送/接收缓冲区中数据的数量
  • datatype:元素类型的 MPI 数据类型句柄
  • op:MPI_Op 类型的操作句柄,用作归约运算(如 MPI_SUM、MPI_MAX 等)
  • comm:进程的 MPI 通信域,即进程所属的组

代码实例:

#include <mpi.h>
#include <stdio.h>
#include <stdlib.h>

int main(int argc, char** argv) {
    int rank, size, sum;
    int global_sum;
    MPI_Init(&argc, &argv);
    MPI_Comm_rank(MPI_COMM_WORLD, &rank);
    MPI_Comm_size(MPI_COMM_WORLD, &size);

    int *sendbuf = (int*)malloc(sizeof(int));
    int *recvbuf = (int*)malloc(sizeof(int));

    *sendbuf = rank;

    MPI_Scan(sendbuf, recvbuf, 1, MPI_INT, MPI_SUM, MPI_COMM_WORLD);

    printf("Rank %d, Sum of all ranks = %d\n", rank, *recvbuf);

    free(sendbuf);
    free(recvbuf);
    MPI_Finalize();
    return 0;
}

Alltoall

每个进程一次将它的发送缓冲区的第i块数据发送给第i个进程,同时每个进程又都一次从第j个进程接收数据放到各自接收缓冲区的第j块数据区的位置。

函数原型:

int MPI_Alltoall(const void* sendbuf, int sendcount, 
MPI_Datatype sendtype, void* recvbuf, int recvcount,
MPI_Datatype recvtype, MPI_Comm comm)

函数参数详解:

  • sendbuf:表示发送缓冲区,用于存储该进程要发送给其他进程的数据。
  • sendcount:表示每个发送缓冲区中的元素数量。
  • sendtype:表示发送数据的数据类型。
  • recvbuf:表示接收缓冲区,用于存储其他进程发送给该进程的数据。
  • recvcount:表示每个接收缓冲区中的元素数量。
  • recvtype:表示接收到的数据的数据类型。
  • comm:表示通信域

代码实例

#include <iostream>
#include <mpi.h>

int main(int argc, char **argv) {
  MPI_Init(&argc, &argv);

  int rank, size;
  MPI_Comm_rank(MPI_COMM_WORLD, &rank);
  MPI_Comm_size(MPI_COMM_WORLD, &size);

  int send_data[4] = {1, 2, 3, 4};
  int recv_data[size * 4];

  MPI_Alltoall(send_data, 1, MPI_INT, recv_data, 1, MPI_INT, MPI_COMM_WORLD);

  for (int i = 0; i < size * 4; i++) {
    std::cout << "Process " << rank << " received " << recv_data[i] << " from process " << i / 4 << std::endl;
  }

  MPI_Finalize();
  return 0;
}

在这里插入图片描述

进程同步

Barrier

相当于在某处设置一个栅栏,到达这里的进程需要在这里等待,直到所有的进程都到达这里,做一个同步的动作。

MPI 进程通常是异步执行的,即每个进程独立地执行它们的任务,与其他进程无关。但是,某些应用程序需要确保所有 MPI 进程在某一点上都到达了一个同步状态,这时就可以使用 MPI_Barrier。

函数原型:

int MPI_Barrier(MPI_Comm comm)

函数参数:

  • comm:表示通信域,所有在该通信域中的进程将进行 MPI_Barrier 同步。

代码实例:

#include <iostream>
#include <mpi.h>

int main(int argc, char **argv) {
  MPI_Init(&argc, &argv);

  int rank, size;
  MPI_Comm_rank(MPI_COMM_WORLD, &rank);
  MPI_Comm_size(MPI_COMM_WORLD, &size);
  std::cout << "Process " << rank << " says hello!" << std::endl;

  MPI_Barrier(MPI_COMM_WORLD);

  std::cout << "Process " << rank << " says goodbye!" << std::endl;

  MPI_Finalize();
  return 0;
}

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

开源django+mysql+vue3前后端分离商城baykeShop使用指南

baykeShop开源商城系统 项目简介 baykeShop&#xff08;拜客商城系统&#xff09;是一款全开源Python栈商城系统&#xff0c;管理后台完全前后端分离重写以适配项目&#xff0c;前后端100%开源&#xff0c;后台前端采用开源SCUI开源库对接开发&#xff0c;美观、易用、符合当…

深入探索C语言自定义类型:打造你的编程世界

一、什么是自定义类型 C语言提供了丰富的内置类型&#xff0c;常见的有int, char, float, double, 以及各种指针。 除此之外&#xff0c;我们还能自己创建一些类型&#xff0c;这些类型称为自定义类型&#xff0c;如数组&#xff0c;结构体&#xff0c;枚举类型和联合体类型。 …

软件架构模式+系统架构

架构模式对比 分层模式 一般信息系统中最常见的4层划分如下&#xff1a; Presentation layer 表示层&#xff08;也就是UI层&#xff09;Application layer 应用层&#xff08;也就是服务层&#xff09;Business logic layer 业务逻辑层&#xff08;也就是领域层&#xff09;…

NS2安装及入门实例——(ns2.35 / Ubuntu20.04)

文章目录 一、ns2安装1、更新系统源2、准备工作3、下载安装包4、安装5、问题① 问题1② 问题2③ 问题3 6、安装成功7、环境配置 二、nam安装1、安装2、问题 三、实例 一、ns2安装 1、更新系统源 sudo apt-get update sudo apt-get upgrade2、准备工作 sudo apt-get install …

图像生成模型【自编码器、RNN、VAE、GAN、Diffusion、AIGC等】

目录 监督学习 与 无监督学习 生成模型 自编码器 从线性维度压缩角度: 2D->1D 线性维度压缩: 3D->2D 推广线性维度压缩 流形 自编码器&#xff1a;流形数据的维度压缩 全图像空间 自然图像流形 自编码器的去噪效果 自编码器的问题 图像预测 (“结构化预测”…

CSS判断手机暗黑模式

手机有个功能到了晚上会自动变成深色也就是暗黑模式.这种情况下网页会自动变颜色.如果想自由控制暗黑模式下的html样式的话,可以用如下方式: media (prefers-color-scheme: dark) {/*html, body {*//*filter: invert(1) hue-rotate(180deg);*//*}*/.maill{margin-left: 0;marg…

哪吒汽车“三头六臂”之「浩智电驱」

撰文 / 翟悦 编审 / 吴晰 8月21日&#xff0c;在哪吒汽车科技日上&#xff0c;哪吒汽车发布“浩智战略2025”以及浩智技术品牌2.0。根据公开信息&#xff0c;主编梳理了以下几点&#xff1a;◎浩智滑板底盘支持400V/800V双平台◎浩智电驱包括180kW 400V电驱系统和250kW 800…

Python的装饰器详解:提升接口自动化测试效率

在接口自动化测试中&#xff0c;我们经常会遇到一些共用的功能&#xff0c;例如请求日志记录、接口鉴权、性能监控等。为了避免在每个接口函数中重复编写这些功能的代码&#xff0c;Python提供了装饰器&#xff08;Decorator&#xff09;的功能&#xff0c;它能够在不修改原有函…

SAP MM学习笔记26- SAP中 振替转记(转移过账)和 在库转送(库存转储)4- Plant间在库转送 之 在库转送Order(有出荷)

SAP 中在库移动 不仅有入库&#xff08;GR&#xff09;&#xff0c;出库&#xff08;GI&#xff09;&#xff0c;也可以是单纯内部的转记或转送。 1&#xff0c;振替转记&#xff08;转移过账&#xff09; 2&#xff0c;在库转送&#xff08;库存转储&#xff09; 1&#xff…

Web安全——信息收集下篇

Web安全 一、网络空间搜索引擎二、扫描敏感目录/文件1、御剑2、7kbstorm3、bbscan4、dirmap5、dirsearch6、gobuster7、网站文件 三、扫描网页备份四、网站头信息收集五、敏感文件搜索1、GitHub搜索2、Google-hacking3、wooyun漏洞库4、网盘搜索5、社工库6、网站注册信息7、js敏…

Vue学习笔记一(2019)

1.Vuex Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态&#xff0c;并以相应的规则保证状态以一种可预测的方式发生变化。 每一个 Vuex 应用的核心就是 store(仓库)。“store”基本上就是一个容器&#xff0c;它包含着你的应用…

【移动机器人】基于JADE改进差分算法的多AGV轨迹规划

最近帮同学做个东西&#xff0c;但是问题在于是之前从没接触过的领域–移动机器人轨迹规划&#xff0c;虽然也是搞机器人的&#xff0c;但是对 AGV 那边的情况是一无所知&#xff0c;这次能完成也算是挑战成功。此次任务目的是多辆AGV小车搬运货物&#xff0c;保证搬运总时间最…

Git学习part1

02.尚硅谷_Git&GitHub_为什么要使用版本控制_哔哩哔哩_bilibili 1.Git必要性 记录代码开发的历史状态 &#xff0c;允许很多人同时修改文件&#xff08;分布式&#xff09;且不会丢失记录 2.版本控制工具应该具备的功能 1&#xff09;协同修改 多人并行不悖的修改服务器端…

MinIO分布式存储k8s集群部署

一、MinIO是什么 MinIO是go开发的&#xff0c;高性能分布式存储&#xff1b;基于GNU AGPL v3开源&#xff0c;可免费使用&#xff1b; 官网&#xff1a;https://min.io/ github: https://github.com/minio/minio 官网宣传MinIO是世界上速度最快的分布式对象存储&#xff1b; …

Typora导出的PDF目录标题自动加编号

Typora导出的PDF目录标题自动加编号 在Typora主题文件夹增加如下文件后&#xff0c;标题便自动加上了编号&#xff1a; https://gitcode.net/as604049322/blog_data/-/blob/master/base.user.css 例如&#xff1a; 但是导出的PDF中&#xff0c;目录却没有编号&#xff1a; 这…

ConsoleApplication17_2项目免杀(Fiber+VEH Hook Load)

加载方式FiberVEH Hook Load Fiber是纤程免杀&#xff0c;VEH是异常报错&#xff0c;hook使用detours来hook VirtualAlloc和sleep&#xff0c;通过异常报错调用实现主动hook 纤程Fiber的概念&#xff1a;纤程是比线程的更小的一个运行单位。可以把一个线程拆分成多个纤程&#…

高可用集群介绍

一、高可用集群概念 高可用集群&#xff08; High Availability Cluster, HA 集群&#xff09;&#xff0c;其中高可用的含义是最大限度地可以使用。从集群 的名字上可以看出&#xff0c;此类集群实现的功能是保障用户的应用程序持久、不间断地提供服务。当应用程序出现故障或…

XSSchallenge1-20

test1 第一题直接在test插入XSS代码即可 test2 第二关对内容进行”“包裹 这里可以采用”>来绕过 test3 代码审计发现这里用了htmlspecialchars函数&#xff0c;这个函数对<>和’ “等进行了转义&#xff0c;这里可以用事件来绕过 test4 这里用了str_replace&a…

vue+elementUI el-table实现单选

if (selection.length > 1) {this.$refs.table.clearSelection();this.$refs.table.toggleRowSelection(selection.pop());}

Kubernetes技术--k8s核心技术持久化存储

有时候需要在集群中进行一些重要的数据进行持久化存储,然后需要的时候再进行挂载,那么下面我们一起来看看如何实现数据的持久化存储操作。 1.nfs网络存储 -1.找一台服务器做nfs的服务端,安装nfs。(这里我们直接在master上实现)。 这里应该找再单独的搭建一个node节点做持…