欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 新闻 > 社会 > 【无标题】

【无标题】

2024/10/25 10:59:19 来源:https://blog.csdn.net/Mr_Tang4/article/details/143223204  浏览:    关键词:【无标题】
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <string.h>#define PAGE_SIZE (2 * 1024 * 1024)  // 2MB 大页/*功能: 根据输入的内存大小和热页比例进行内存的分配和冷热页模拟参数:mem_size: 传入内存大小,必须是 2 的倍数,单位 MBhot_page_ratio: 热页百分比,0 到 100 的整数
*/
int main(int argc, char *argv[]) {if (argc != 3) {fprintf(stderr, "Usage: %s <mem_size_MB> <hot_page_ratio>\n", argv[0]);return 1;}// 解析和校验输入参数size_t mem_size_MB = atoi(argv[1]);int hot_page_ratio = atoi(argv[2]);if (mem_size_MB <= 0 || mem_size_MB % 2 != 0) {fprintf(stderr, "Error: mem_size_MB must be a positive multiple of 2.\n");return 1;}if (hot_page_ratio < 0 || hot_page_ratio > 100) {fprintf(stderr, "Error: hot_page_ratio must be an integer between 0 and 100.\n");return 1;}// 将 mem_size_MB 转换为字节,并确保是大页大小的倍数size_t size = mem_size_MB * 1024 * 1024;  // 转换为字节size_t total_pages = size / PAGE_SIZE;  // 计算总页数size_t hot_pages = total_pages * hot_page_ratio / 100;  // 计算热页数size_t cold_pages = total_pages - hot_pages;  // 计算冷页数printf("Total pages: %zu, Hot pages: %zu, Cold pages: %zu\n", total_pages, hot_pages, cold_pages);// 分配大页内存char *mem = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_HUGETLB, -1, 0);if (mem == MAP_FAILED) {perror("mmap failed");return 1;}printf("Memory allocated using huge pages.\n");size_t cold_page_access_round = 100;  // 每100轮热页循环后访问冷页一次size_t round = 1;// 无限循环,模拟持续的冷热页访问while (1) {// 模拟热页访问for (size_t i = 0; i < hot_pages; i++) {for (size_t j = 0; j < 1024; j++) {  // 多次访问每个大页mem[i * PAGE_SIZE + (j * 2048)] = i % 256;}}printf("Hot pages accessed frequently.\n");// 模拟冷页访问if (round % cold_page_access_round == 0) {for (size_t i = hot_pages; i < total_pages; i++) {mem[i * PAGE_SIZE] = i % 256;}printf("Cold pages accessed occasionally.\n");round = 0;}round++;}// 虽然程序无限循环,仍可以在退出前释放内存// munmap(mem, size);return 0;
}

添加信号处理函数

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <string.h>
#include <signal.h>#define PAGE_SIZE (2 * 1024 * 1024)  // 2MB 大页// 信号处理函数
void handle_sigint(int sig) {printf("\nCaught signal %d, cleaning up and exiting...\n", sig);if (mem != MAP_FAILED && mem != NULL) {munmap(mem, size);  // 释放 mmap 分配的内存printf("Memory successfully unmapped.\n");}exit(0);  // 退出程序
}/*功能: 根据输入的内存大小和热页比例进行内存的分配和冷热页模拟参数:mem_size: 传入内存大小,必须是 2 的倍数,单位 MBhot_page_ratio: 热页百分比,0 到 100 的整数
*/
int main(int argc, char *argv[]) {if (argc != 3) {fprintf(stderr, "Usage: %s <mem_size_MB> <hot_page_ratio>\n", argv[0]);return 1;}// 解析和校验输入参数size_t mem_size_MB = atoi(argv[1]);int hot_page_ratio = atoi(argv[2]);if (mem_size_MB <= 0 || mem_size_MB % 2 != 0) {fprintf(stderr, "Error: mem_size_MB must be a positive multiple of 2.\n");return 1;}if (hot_page_ratio < 0 || hot_page_ratio > 100) {fprintf(stderr, "Error: hot_page_ratio must be an integer between 0 and 100.\n");return 1;}// 将 mem_size_MB 转换为字节,并确保是大页大小的倍数size_t size = mem_size_MB * 1024 * 1024;  // 转换为字节size_t total_pages = size / PAGE_SIZE;  // 计算总页数size_t hot_pages = total_pages * hot_page_ratio / 100;  // 计算热页数size_t cold_pages = total_pages - hot_pages;  // 计算冷页数printf("Total pages: %zu, Hot pages: %zu, Cold pages: %zu\n", total_pages, hot_pages, cold_pages);signal(SIGINT, handle_sigint); // 捕捉 Ctrl+Csignal(SIGTERM, handle_sigint); // 捕捉 kill// 分配大页内存char *mem = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_HUGETLB, -1, 0);if (mem == MAP_FAILED) {perror("mmap failed");return 1;}printf("Memory allocated using huge pages.\n");size_t cold_page_access_round = 100;  // 每100轮热页循环后访问冷页一次size_t round = 1;// 无限循环,模拟持续的冷热页访问while (1) {// 模拟热页访问for (size_t i = 0; i < hot_pages; i++) {for (size_t j = 0; j < 1024; j++) {  // 多次访问每个大页mem[i * PAGE_SIZE + (j * 2048)] = i % 256;}}printf("Hot pages accessed frequently.\n");// 模拟冷页访问if (round % cold_page_access_round == 0) {for (size_t i = hot_pages; i < total_pages; i++) {mem[i * PAGE_SIZE] = i % 256;}printf("Cold pages accessed occasionally.\n");round = 0;}round++;}return 0;
}

内存地址及大小作为全局变量

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <string.h>
#include <signal.h>#define PAGE_SIZE (2 * 1024 * 1024)  // 2MB 大页char *mem;
size_t size;
/*功能: 根据输入的内存大小和热页比例进行内存的分配和冷热页模拟参数:mem_size: 传入内存大小,必须是 2 的倍数,单位 MBhot_page_ratio: 热页百分比,0 到 100 的整数
*/// 信号处理函数
void handle_sigint(int sig) {printf("\nCaught signal %d, cleaning up and exiting...\n", sig);if (mem != MAP_FAILED && mem != NULL) {munmap(mem, size);  // 释放 mmap 分配的内存printf("Memory successfully unmapped.\n");}exit(0);  // 退出程序
}int main(int argc, char *argv[]) {if (argc != 3) {fprintf(stderr, "Usage: %s <mem_size_MB> <hot_page_ratio>\n", argv[0]);return 1;}// 解析和校验输入参数size_t mem_size_MB = atoi(argv[1]);int hot_page_ratio = atoi(argv[2]);if (mem_size_MB <= 0 || mem_size_MB % 2 != 0) {fprintf(stderr, "Error: mem_size_MB must be a positive multiple of 2.\n");return 1;}if (hot_page_ratio < 0 || hot_page_ratio > 100) {fprintf(stderr, "Error: hot_page_ratio must be an integer between 0 and 100.\n");return 1;}// 将 mem_size_MB 转换为字节,并确保是大页大小的倍数size = mem_size_MB * 1024 * 1024;  // 转换为字节size_t total_pages = size / PAGE_SIZE;  // 计算总页数size_t hot_pages = total_pages * hot_page_ratio / 100;  // 计算热页数size_t cold_pages = total_pages - hot_pages;  // 计算冷页数printf("Total pages: %zu, Hot pages: %zu, Cold pages: %zu\n", total_pages, hot_pages, cold_pages);signal(SIGINT, handle_sigint); // 捕捉 Ctrl+Csignal(SIGTERM, handle_sigint); // 捕捉 kill// 分配大页内存mem = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_HUGETLB, -1, 0);if (mem == MAP_FAILED) {perror("mmap failed");return 1;}printf("Memory allocated using huge pages.\n");size_t cold_page_access_round = 100;  // 每100轮热页循环后访问冷页一次size_t round = 1;// 无限循环,模拟持续的冷热页访问while (1) {// 模拟热页访问for (size_t i = 0; i < hot_pages; i++) {for (size_t j = 0; j < 1024; j++) {  // 多次访问每个大页mem[i * PAGE_SIZE + (j * 2048)] = i % 256;}}printf("Hot pages accessed frequently.\n");// 模拟冷页访问if (round % cold_page_access_round == 0) {for (size_t i = hot_pages; i < total_pages; i++) {mem[i * PAGE_SIZE] = i % 256;}printf("Cold pages accessed occasionally.\n");round = 0;}round++;}return 0;
}

这段代码使用mmap函数进行内存映射操作,主要功能是分配一块特定大小的内存区域。以下是对各个参数的解释:

  1. NULL:表示让内核选择合适的地址来映射内存。通常情况下,内核会选择一个合适的地址,这样可以提高可移植性。
  2. size:这是要分配的内存大小。在你的代码中,size是根据用户输入的内存大小(以字节为单位)计算得到的。
  3. PROT_READ | PROT_WRITE:指定了对映射内存的访问权限。这里表示映射的内存区域可读可写。
    • PROT_READ表示允许读取内存区域。
    • PROT_WRITE表示允许写入内存区域。
  4. MAP_PRIVATE | MAP_ANONYMOUS | MAP_HUGETLB:这是一组标志,用于控制内存映射的行为。
    • MAP_PRIVATE表示创建一个私有的、写时复制的内存映射。对这个映射区域的修改不会影响到原始文件(因为这里没有映射文件,是匿名映射),也不会被其他进程看到。
    • MAP_ANONYMOUS表示创建一个匿名映射,即不与任何文件关联。通常用于分配内存而不是映射文件。
    • MAP_HUGETLB表示使用大页内存(HugeTLB)进行映射。大页内存可以提高内存访问性能,但不是所有系统都支持,并且可能需要特定的配置。
  5. -1:在这个上下文中,这是文件描述符参数。因为是匿名映射,所以使用-1表示不与任何文件关联。
  6. 0:这是文件偏移量参数。对于匿名映射,通常设置为0

综上所述,这段代码的作用是分配一块特定大小的、可读可写的、私有的匿名大页内存区域,并将该内存区域的起始地址赋值给指针mem。如果分配成功,mem将指向这块新分配的内存区域;如果分配失败,mem将被设置为MAP_FAILED

信号处理函数

#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <unistd.h>// 信号处理函数
void handle_signal(int signal) {if (signal == SIGINT) {printf("Caught SIGINT (Ctrl+C)\n");} else if (signal == SIGTERM) {printf("Caught SIGTERM (kill)\n");exit(0);  // 退出程序} else if (signal == SIGHUP) {printf("Caught SIGHUP (Terminal closed or session ended)\n");} else {printf("Caught signal %d\n", signal);}
}int main() {// 捕获 SIGINT, SIGTERM, SIGHUP 信号signal(SIGINT, handle_signal);   // Ctrl+C 产生 SIGINTsignal(SIGTERM, handle_signal);  // kill 命令默认发送 SIGTERMsignal(SIGHUP, handle_signal);   // SIGHUP 通常在终端关闭时触发printf("Program started. PID: %d\n", getpid());// 无限循环,等待信号while (1) {printf("Running... (Press Ctrl+C to stop or use kill)\n");sleep(2);  // 睡眠2秒,模拟程序运行}return 0;
}

在这段 C 语言代码中,signal(SIGINT, handle_signal);是用来设置信号处理函数的。

以下是对这一用法的详细解释:

  1. signal函数的作用

    • signal是 C 语言标准库中的一个函数,用于设置特定信号的处理方式。它接受两个参数,一个是要处理的信号编号,另一个是信号处理函数的指针。
    • 在你的代码中,signal(SIGINT, handle_signal);表示当程序接收到SIGINT信号(通常由用户在终端按下Ctrl + C产生)时,调用handle_signal函数来处理这个信号。
  2. 参数说明

    • SIGINT:这是一个预定义的信号常量,表示中断信号。当用户在终端按下Ctrl + C时,操作系统会向正在运行的程序发送这个信号,以请求程序终止。
    • handle_signal:这是一个用户定义的函数指针,指向信号处理函数。信号处理函数的原型通常是void func(int sig);,其中sig是接收到的信号编号。在你的代码中,handle_signal函数根据接收到的不同信号打印不同的消息。
  3. 信号处理流程

    • 当程序运行时,系统会将SIGINT信号与handle_signal函数关联起来。
    • 如果在程序运行过程中,用户按下Ctrl + C,操作系统会向程序发送SIGINT信号。
    • 程序接收到SIGINT信号后,会中断当前正在执行的代码流程,并跳转到handle_signal函数执行。在handle_signal函数中,根据接收到的信号编号进行相应的处理,在这个例子中是打印一条消息说明捕获到了SIGINT信号。
    • 信号处理函数执行完毕后,程序可以根据需要决定是否继续执行或者终止。

总的来说,signal(SIGINT, handle_signal);的作用是让程序能够捕获和处理特定的信号,从而实现对用户操作(如中断程序)或系统事件(如终端关闭)的响应。

#include <stdlib.h>  // 需要使用rand()函数// 在冷页访问部分,添加一个概率判断
for (size_t i = HOT_PAGES; i < TOTAL_PAGES; i++) {if (rand() % 10 == 0) {  // 10%的概率访问冷页mem[i * PAGE_SIZE] = i % 256;}
}

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com