256版
#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 的倍数,单位 MB
hot_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;
// 初始化申请到的内存--赋值
for (size_t i = 0; i < hot_pages; i++) {
for (size_t j = 0; j < 1024; j++) { // 多次访问每个大页
mem[i * PAGE_SIZE + (j * 2048)] = (i + j * 2048) % 256; // 每隔2048字节,写一个,一个2M页,要写2^21/2^11 = 1024次
}
}
for (size_t i = hot_pages; i < total_pages; i++) {
mem[i * PAGE_SIZE] = i % 256; //给2M大页标记序号
}
printf("The allocated memory has been initialized!\n");
// 无限循环,模拟持续的冷热页访问
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;
if (mem[i * PAGE_SIZE + (j * 2048)] != (i + j * 2048) % 256) {
printf("Hot pages accessed error!\n");
}
}
}
printf("Hot pages accessed frequently and successfully.\n");
// 模拟冷页访问
if (round % cold_page_access_round == 0) {
for (size_t i = hot_pages; i < total_pages; i++) {
// mem[i * PAGE_SIZE] = i % 256;
if (mem[i * PAGE_SIZE] != i % 256) {
printf("Cold pages accessed error!\n");
}
}
printf("Cold pages accessed occasionally and successfully.\n");
round = 0;
}
round++;
}
// 虽然程序无限循环,仍可以在退出前释放内存
// munmap(mem, size);
return 0;
}
int *版
#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 的倍数,单位 MB
hot_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);
// 分配大页内存
int *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;
// 初始化申请到的内存--赋值
for (size_t i = 0; i < hot_pages; i++) {
for (size_t j = 0; j < 1024; j++) { // 多次访问每个大页
mem[i * PAGE_SIZE / sizeof(int) + (j * 2048 / sizeof(int))] = i + j * 2048; // 4个字节为一个下标
}
}
for (size_t i = hot_pages; i < total_pages; i++) {
mem[i * PAGE_SIZE / sizeof(int)] = i; //给2M大页标记序号
}
printf("The allocated memory has been initialized!\n");
// 无限循环,模拟持续的冷热页访问
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;
if (mem[i * PAGE_SIZE / sizeof(int) + (j * 2048 / sizeof(int))] != i + j * 2048) {
printf("Hot pages accessed error!\n");
}
}
}
printf("Hot pages accessed frequently and successfully.\n");
// 模拟冷页访问
if (round % cold_page_access_round == 0) {
for (size_t i = hot_pages; i < total_pages; i++) {
// mem[i * PAGE_SIZE] = i % 256;
if (mem[i * PAGE_SIZE / sizeof(int)] != i) {
printf("Cold pages accessed error!\n");
}
}
printf("Cold pages accessed occasionally and successfully.\n");
round = 0;
}
round++;
}
// 虽然程序无限循环,仍可以在退出前释放内存
// munmap(mem, size);
return 0;
}
int 改进
#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 大页
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;
}
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);
int *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;
size_t round = 1;
// 预先计算除法
size_t page_size_in_ints = PAGE_SIZE / sizeof(int);
size_t offset_2048_in_ints = 2048 / sizeof(int);
// 初始化申请到的内存
for (size_t i = 0; i < hot_pages; i++) {
for (size_t j = 0; j < page_size_in_ints; j++) {
if (j * offset_2048_in_ints < page_size_in_ints) {
mem[i * page_size_in_ints + j * offset_2048_in_ints] = i + j * 2048;
}
}
}
for (size_t i = hot_pages; i < total_pages; i++) {
mem[i * page_size_in_ints] = i;
}
printf("The allocated memory has been initialized!\n");
// 无限循环,模拟冷热页访问
while (1) {
for (size_t i = 0; i < hot_pages; i++) {
for (size_t j = 0; j < page_size_in_ints; j++) {
if (mem[i * page_size_in_ints + j * offset_2048_in_ints] != i + j * 2048) {
printf("Hot pages accessed error at page %zu, index %zu!\n", i, j);
}
}
}
printf("Hot pages accessed frequently and successfully.\n");
if (round % cold_page_access_round == 0) {
for (size_t i = hot_pages; i < total_pages; i++) {
if (mem[i * page_size_in_ints] != i) {
printf("Cold pages accessed error at page %zu!\n", i);
}
}
printf("Cold pages accessed occasionally and successfully.\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 的倍数,单位 MB
hot_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+C
signal(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 的倍数,单位 MB
hot_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+C
signal(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函数进行内存映射操作,主要功能是分配一块特定大小的内存区域。以下是对各个参数的解释:
NULL:表示让内核选择合适的地址来映射内存。通常情况下,内核会选择一个合适的地址,这样可以提高可移植性。size:这是要分配的内存大小。在你的代码中,size是根据用户输入的内存大小(以字节为单位)计算得到的。PROT_READ | PROT_WRITE:指定了对映射内存的访问权限。这里表示映射的内存区域可读可写。PROT_READ表示允许读取内存区域。PROT_WRITE表示允许写入内存区域。
MAP_PRIVATE | MAP_ANONYMOUS | MAP_HUGETLB:这是一组标志,用于控制内存映射的行为。MAP_PRIVATE表示创建一个私有的、写时复制的内存映射。对这个映射区域的修改不会影响到原始文件(因为这里没有映射文件,是匿名映射),也不会被其他进程看到。MAP_ANONYMOUS表示创建一个匿名映射,即不与任何文件关联。通常用于分配内存而不是映射文件。MAP_HUGETLB表示使用大页内存(HugeTLB)进行映射。大页内存可以提高内存访问性能,但不是所有系统都支持,并且可能需要特定的配置。
-1:在这个上下文中,这是文件描述符参数。因为是匿名映射,所以使用-1表示不与任何文件关联。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 产生 SIGINT
signal(SIGTERM, handle_signal); // kill 命令默认发送 SIGTERM
signal(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);是用来设置信号处理函数的。
以下是对这一用法的详细解释:
-
signal函数的作用:signal是 C 语言标准库中的一个函数,用于设置特定信号的处理方式。它接受两个参数,一个是要处理的信号编号,另一个是信号处理函数的指针。- 在你的代码中,
signal(SIGINT, handle_signal);表示当程序接收到SIGINT信号(通常由用户在终端按下Ctrl + C产生)时,调用handle_signal函数来处理这个信号。
-
参数说明:
SIGINT:这是一个预定义的信号常量,表示中断信号。当用户在终端按下Ctrl + C时,操作系统会向正在运行的程序发送这个信号,以请求程序终止。handle_signal:这是一个用户定义的函数指针,指向信号处理函数。信号处理函数的原型通常是void func(int sig);,其中sig是接收到的信号编号。在你的代码中,handle_signal函数根据接收到的不同信号打印不同的消息。
-
信号处理流程:
- 当程序运行时,系统会将
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;
}
}
int * char *
#include <stdio.h>
#include <stdlib.h>
int main() {
// 使用 malloc 分配内存
size_t char_array_size = 5; // char 数组大小
size_t int_array_size = 5; // int 数组大小
// 分配 char 数组
char *char_array = (char *)malloc(char_array_size * sizeof(char));
if (char_array == NULL) {
perror("Failed to allocate memory for char_array");
return 1;
}
// 分配 int 数组
int *int_array = (int *)malloc(int_array_size * sizeof(int));
if (int_array == NULL) {
perror("Failed to allocate memory for int_array");
free(char_array); // 释放已分配的内存
return 1;
}
// 初始化和打印 char 数组
for (size_t i = 0; i < char_array_size; i++) {
char_array[i] = 'A' + i; // 存储字符 A, B, C, D, E
}
printf("Char array: ");
for (size_t i = 0; i < char_array_size; i++) {
printf("%c ", char_array[i]);
}
printf("\n");
// 初始化和打印 int 数组
for (size_t i = 0; i < int_array_size; i++) {
int_array[i] = (i + 1) * 10; // 存储 10, 20, 30, 40, 50
}
printf("Int array: ");
for (size_t i = 0; i < int_array_size; i++) {
printf("%d ", int_array[i]);
}
printf("\n");
// 释放内存
free(char_array);
free(int_array);
return 0;
}
mmap
#include <stdio.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <unistd.h>
#define SIZE 5 * 1024 * 1024 // 分配 5MB 的内存
int main() {
// 使用 mmap 分配内存
char *char_mem = mmap(NULL, SIZE, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
if (char_mem == MAP_FAILED) {
perror("Failed to allocate memory for char_mem");
return 1;
}
int *int_mem = mmap(NULL, SIZE, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
if (int_mem == MAP_FAILED) {
perror("Failed to allocate memory for int_mem");
munmap(char_mem, SIZE); // 释放 char_mem
return 1;
}
// 初始化 char 数组
for (size_t i = 0; i < 10; i++) {
// char_mem[i] = 'A' + i; // 存储字符 A, B, C, D, E, F, G, H, I, J
char_mem[i] = i;
}
printf("Char array: ");
for (size_t i = 0; i < 10; i++) {
printf("%c ", char_mem[i]);
}
printf("\n");
// 初始化 int 数组
for (size_t i = 0; i < 10; i++) {
int_mem[i] = (i + 1) * 10; // 存储 10, 20, 30, 40, 50, 60, 70, 80, 90, 100
}
printf("Int array: ");
for (size_t i = 0; i < 10; i++) {
printf("%d ", int_mem[i]);
}
printf("\n");
// 释放内存
munmap(char_mem, SIZE);
munmap(int_mem, SIZE);
return 0;
}

9082

被折叠的 条评论
为什么被折叠?



