mlockall 函数详解 Link to heading

1. 函数介绍 Link to heading

mlockall 是 Linux 系统中用于锁定进程所有内存页面的系统调用。可以把 mlockall 想象成"内存保护盾"——它能够将进程的所有内存页面锁定在物理内存中,防止它们被交换到磁盘的交换空间(swap)中。

在实时系统或对性能要求极高的应用中,内存交换会导致不可预测的延迟,因为从磁盘读取页面比从物理内存读取要慢得多。mlockall 确保关键进程的内存始终保持在物理内存中,从而提供确定性的性能表现。

2. 函数原型 Link to heading

#include <sys/mman.h>

int mlockall(int flags);

3. 功能 Link to heading

mlockall 函数用于将调用进程的所有内存页面锁定在物理内存中,防止它们被交换到磁盘。这包括:

  • 已经分配的内存页面
  • 未来可能分配的内存页面(取决于 flags 参数)

4. 参数 Link to heading

  • flags: 控制锁定行为的标志位,可以是以下值的按位或组合:
标志 说明
MCL_CURRENT 1 锁定当前已映射的所有页面
MCL_FUTURE 2 锁定未来映射的所有页面

5. 标志位详细说明 Link to heading

MCL_CURRENT Link to heading

  • 锁定进程当前已经映射到地址空间的所有内存页面
  • 包括代码段、数据段、堆、栈、共享库等
  • 不包括未来可能分配的内存

MCL_FUTURE Link to heading

  • 锁定进程未来映射的所有页面
  • 对后续的 mmapsbrk 等内存分配操作生效
  • 不影响已经存在的页面

组合使用 Link to heading

  • MCL_CURRENT | MCL_FUTURE: 锁定当前和未来的所有页面

6. 返回值 Link to heading

  • 成功: 返回 0
  • 失败: 返回 -1,并设置相应的 errno 错误码

7. 常见错误码 Link to heading

  • EPERM: 权限不足(通常需要 root 权限或适当的能力)
  • ENOMEM: 内存不足或超出限制
  • EINVAL: flags 参数无效
  • ENOSYS: 系统不支持内存锁定

8. 相关函数或关联函数 Link to heading

  • mlock: 锁定指定内存区域
  • munlock: 解锁指定内存区域
  • munlockall: 解锁所有内存页面
  • setrlimit: 设置资源限制(RLIMIT_MEMLOCK)
  • getrlimit: 获取资源限制
  • mmap: 内存映射
  • brk/sbrk: 调整程序断点

9. 示例代码 Link to heading

示例1:基础用法 - 内存锁定演示 Link to heading

#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/mman.h>
#include <sys/resource.h>
#include <errno.h>
#include <string.h>
#include <time.h>

// 显示内存锁定限制
void show_memory_lock_limits() {
    struct rlimit limit;
    
    printf("=== 内存锁定限制 ===\n");
    
    if (getrlimit(RLIMIT_MEMLOCK, &limit) == 0) {
        printf("最大可锁定内存:\n");
        printf("  软限制: ");
        if (limit.rlim_cur == RLIM_INFINITY) {
            printf("无限制");
        } else {
            printf("%lu 字节 (%.2f MB)", 
                   (unsigned long)limit.rlim_cur,
                   (double)limit.rlim_cur / (1024 * 1024));
        }
        printf("\n");
        
        printf("  硬限制: ");
        if (limit.rlim_max == RLIM_INFINITY) {
            printf("无限制");
        } else {
            printf("%lu 字节 (%.2f MB)", 
                   (unsigned long)limit.rlim_max,
                   (double)limit.rlim_max / (1024 * 1024));
        }
        printf("\n");
    } else {
        printf("无法获取内存锁定限制: %s\n", strerror(errno));
    }
    
    printf("当前用户 UID: %d\n", getuid());
    printf("当前进程 PID: %d\n", getpid());
    printf("\n");
}

// 分配并使用内存
void allocate_and_use_memory(size_t size_mb) {
    size_t size_bytes = size_mb * 1024 * 1024;
    char *buffer = malloc(size_bytes);
    
    if (buffer) {
        printf("分配内存: %zu MB (%p)\n", size_mb, (void*)buffer);
        
        // 使用内存(写入数据)
        printf("写入数据到内存...\n");
        for (size_t i = 0; i < size_bytes; i += 4096) {
            buffer[i] = (char)(i % 256);
        }
        
        // 访问内存(读取数据)
        printf("读取数据验证...\n");
        volatile long sum = 0;
        for (size_t i = 0; i < size_bytes; i += 4096) {
            sum += buffer[i];
        }
        
        printf("内存使用完成\n");
        
        // 不立即释放,让 mlockall 生效
        // free(buffer);
    } else {
        printf("内存分配失败\n");
    }
}

int main() {
    printf("=== mlockall 基础示例 ===\n\n");
    
    // 显示系统信息
    show_memory_lock_limits();
    
    // 1. 尝试锁定当前内存
    printf("1. 尝试锁定当前内存 (MCL_CURRENT):\n");
    if (mlockall(MCL_CURRENT) == 0) {
        printf("  ✓ 成功锁定当前内存\n");
    } else {
        if (errno == EPERM) {
            printf("  ⚠ 权限不足: 需要 root 权限或 CAP_IPC_LOCK 能力\n");
        } else {
            printf("  ✗ 锁定失败: %s\n", strerror(errno));
        }
    }
    
    // 2. 尝试锁定当前和未来内存
    printf("\n2. 尝试锁定当前和未来内存 (MCL_CURRENT | MCL_FUTURE):\n");
    if (mlockall(MCL_CURRENT | MCL_FUTURE) == 0) {
        printf("  ✓ 成功锁定当前和未来内存\n");
    } else {
        if (errno == EPERM) {
            printf("  ⚠ 权限不足: 需要 root 权限或 CAP_IPC_LOCK 能力\n");
        } else {
            printf("  ✗ 锁定失败: %s\n", strerror(errno));
        }
    }
    
    // 3. 分配和使用内存
    printf("\n3. 分配和使用内存:\n");
    allocate_and_use_memory(10);  // 分配 10MB 内存
    
    // 4. 检查锁定状态
    printf("\n4. 检查内存锁定效果:\n");
    printf("  内存页面已被锁定(如果权限允许)\n");
    printf("  这些页面不会被交换到磁盘\n");
    
    // 5. 解锁所有内存
    printf("\n5. 解锁所有内存:\n");
    if (munlockall() == 0) {
        printf("  ✓ 成功解锁所有内存\n");
    } else {
        printf("  ✗ 解锁失败: %s\n", strerror(errno));
    }
    
    printf("\n=== 说明 ===\n");
    printf("1. 内存锁定需要适当权限(root 或 CAP_IPC_LOCK)\n");
    printf("2. 锁定的内存不会被交换到磁盘\n");
    printf("3. 过度使用可能导致系统内存不足\n");
    printf("4. 应该在不需要时及时解锁内存\n");
    
    return 0;
}

示例2:实时应用内存锁定 Link to heading

#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/mman.h>
#include <sys/resource.h>
#include <errno.h>
#include <string.h>
#include <signal.h>
#include <time.h>
#include <pthread.h>

// 全局变量用于演示内存锁定效果
volatile int running = 1;
char *locked_buffer = NULL;
size_t buffer_size = 50 * 1024 * 1024;  // 50MB

// 信号处理函数
void signal_handler(int sig) {
    printf("\n收到信号 %d,准备退出...\n", sig);
    running = 0;
}

// 设置信号处理
void setup_signal_handlers() {
    struct sigaction sa;
    sa.sa_handler = signal_handler;
    sigemptyset(&sa.sa_mask);
    sa.sa_flags = 0;
    
    sigaction(SIGINT, &sa, NULL);   // Ctrl+C
    sigaction(SIGTERM, &sa, NULL);  // 终止信号
}

// 实时任务函数
void* real_time_task(void* arg) {
    struct timespec start, end;
    long iterations = 0;
    double min_time = 1e9, max_time = 0, total_time = 0;
    
    printf("实时任务开始运行...\n");
    printf("按 Ctrl+C 停止\n\n");
    
    while (running) {
        clock_gettime(CLOCK_MONOTONIC, &start);
        
        // 访问锁定的内存
        if (locked_buffer) {
            // 在缓冲区中进行一些计算
            for (size_t i = 0; i < buffer_size; i += 4096) {
                locked_buffer[i] = (locked_buffer[i] + 1) % 256;
            }
        }
        
        clock_gettime(CLOCK_MONOTONIC, &end);
        
        // 计算执行时间(纳秒)
        double elapsed = (end.tv_sec - start.tv_sec) * 1e9 + 
                        (end.tv_nsec - start.tv_nsec);
        
        total_time += elapsed;
        if (elapsed < min_time) min_time = elapsed;
        if (elapsed > max_time) max_time = elapsed;
        
        iterations++;
        
        // 每 1000 次迭代显示一次统计
        if (iterations % 1000 == 0) {
            printf("迭代 %ld: 平均 %.2f ns, 最小 %.2f ns, 最大 %.2f ns\n",
                   iterations, total_time / iterations, min_time, max_time);
        }
        
        // 短暂延迟
        struct timespec delay = {0, 100000};  // 100 微秒
        nanosleep(&delay, NULL);
    }
    
    printf("\n实时任务完成:\n");
    printf("  总迭代次数: %ld\n", iterations);
    printf("  平均执行时间: %.2f ns\n", total_time / iterations);
    printf("  最小执行时间: %.2f ns\n", min_time);
    printf("  最大执行时间: %.2f ns\n", max_time);
    
    return NULL;
}

// 显示内存状态
void show_memory_status() {
    printf("=== 内存状态 ===\n");
    
    // 显示进程内存使用情况
    FILE *status_file = fopen("/proc/self/status", "r");
    if (status_file) {
        char line[256];
        while (fgets(line, sizeof(line), status_file)) {
            if (strncmp(line, "VmSize:", 7) == 0 ||
                strncmp(line, "VmRSS:", 6) == 0 ||
                strncmp(line, "VmData:", 7) == 0) {
                printf("  %s", line);
            }
        }
        fclose(status_file);
    }
    
    printf("\n");
}

int main() {
    pthread_t task_thread;
    
    printf("=== 实时应用内存锁定示例 ===\n\n");
    
    // 设置信号处理
    setup_signal_handlers();
    
    // 显示初始内存状态
    show_memory_status();
    
    // 显示内存锁定限制
    struct rlimit limit;
    if (getrlimit(RLIMIT_MEMLOCK, &limit) == 0) {
        printf("内存锁定限制: ");
        if (limit.rlim_cur == RLIM_INFINITY) {
            printf("无限制\n");
        } else {
            printf("%.2f MB\n", (double)limit.rlim_cur / (1024 * 1024));
        }
    }
    
    // 分配内存缓冲区
    printf("分配内存缓冲区: %.2f MB\n", (double)buffer_size / (1024 * 1024));
    locked_buffer = malloc(buffer_size);
    if (!locked_buffer) {
        perror("内存分配失败");
        return 1;
    }
    
    // 初始化缓冲区
    printf("初始化缓冲区...\n");
    memset(locked_buffer, 0, buffer_size);
    
    // 尝试锁定所有内存
    printf("尝试锁定所有内存...\n");
    if (mlockall(MCL_CURRENT | MCL_FUTURE) == 0) {
        printf("✓ 成功锁定所有内存\n");
        printf("内存页面将不会被交换到磁盘\n");
    } else {
        if (errno == EPERM) {
            printf("⚠ 权限不足: 以普通用户权限运行,内存可能被交换\n");
            printf("  建议使用 sudo 运行以获得最佳实时性能\n");
        } else {
            printf("✗ 内存锁定失败: %s\n", strerror(errno));
        }
    }
    
    show_memory_status();
    
    // 创建实时任务线程
    printf("启动实时任务线程...\n");
    if (pthread_create(&task_thread, NULL, real_time_task, NULL) != 0) {
        perror("创建线程失败");
        free(locked_buffer);
        return 1;
    }
    
    // 等待线程完成
    pthread_join(task_thread, NULL);
    
    // 清理解锁
    printf("\n清理资源...\n");
    if (munlockall() == 0) {
        printf("✓ 成功解锁所有内存\n");
    } else {
        printf("✗ 解锁失败: %s\n", strerror(errno));
    }
    
    free(locked_buffer);
    
    printf("\n=== 实时应用说明 ===\n");
    printf("内存锁定的优势:\n");
    printf("1. 防止页面交换导致的延迟抖动\n");
    printf("2. 提供确定性的内存访问时间\n");
    printf("3. 适用于实时音频/视频处理\n");
    printf("4. 适用于高频交易系统\n");
    printf("\n");
    printf("注意事项:\n");
    printf("1. 需要适当权限(root 或 CAP_IPC_LOCK)\n");
    printf("2. 过度使用可能导致系统内存不足\n");
    printf("3. 应该在应用结束时解锁内存\n");
    
    return 0;
}

示例3:完整的内存锁定管理工具 Link to heading

#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/mman.h>
#include <sys/resource.h>
#include <errno.h>
#include <string.h>
#include <getopt.h>
#include <time.h>
#include <sys/stat.h>

// 配置结构体
struct lock_config {
    int lock_current;   // 锁定当前内存
    int lock_future;    // 锁定未来内存
    int unlock_all;     // 解锁所有内存
    int show_status;    // 显示状态信息
    int verbose;        // 详细输出
    size_t test_memory; // 测试内存大小(MB)
};

// 显示内存锁定限制
void show_lock_limits() {
    struct rlimit limit;
    
    printf("=== 内存锁定限制 ===\n");
    
    if (getrlimit(RLIMIT_MEMLOCK, &limit) == 0) {
        printf("最大可锁定内存:\n");
        printf("  软限制: ");
        if (limit.rlim_cur == RLIM_INFINITY) {
            printf("无限制");
        } else {
            printf("%lu 字节 (%.2f MB)", 
                   (unsigned long)limit.rlim_cur,
                   (double)limit.rlim_cur / (1024 * 1024));
        }
        printf("\n");
        
        printf("  硬限制: ");
        if (limit.rlim_max == RLIM_INFINITY) {
            printf("无限制");
        } else {
            printf("%lu 字节 (%.2f MB)", 
                   (unsigned long)limit.rlim_max,
                   (double)limit.rlim_max / (1024 * 1024));
        }
        printf("\n");
    } else {
        printf("无法获取内存锁定限制: %s\n", strerror(errno));
    }
    
    printf("当前用户 UID: %d\n", getuid());
    printf("进程 PID: %d\n", getpid());
    printf("\n");
}

// 显示进程内存状态
void show_process_memory_status() {
    printf("=== 进程内存状态 ===\n");
    
    FILE *status_file = fopen("/proc/self/status", "r");
    if (status_file) {
        char line[256];
        while (fgets(line, sizeof(line), status_file)) {
            if (strncmp(line, "VmSize:", 7) == 0 ||
                strncmp(line, "VmRSS:", 6) == 0 ||
                strncmp(line, "VmData:", 7) == 0 ||
                strncmp(line, "VmStk:", 6) == 0 ||
                strncmp(line, "VmExe:", 6) == 0 ||
                strncmp(line, "VmLib:", 6) == 0) {
                printf("%s", line);
            }
        }
        fclose(status_file);
    } else {
        printf("无法读取进程内存状态\n");
    }
    printf("\n");
}

// 显示系统内存信息
void show_system_memory_info() {
    printf("=== 系统内存信息 ===\n");
    
    FILE *meminfo = fopen("/proc/meminfo", "r");
    if (meminfo) {
        char line[256];
        int count = 0;
        while (fgets(line, sizeof(line), meminfo) && count < 6) {
            if (strncmp(line, "MemTotal:", 9) == 0 ||
                strncmp(line, "MemFree:", 8) == 0 ||
                strncmp(line, "MemAvailable:", 13) == 0 ||
                strncmp(line, "SwapTotal:", 10) == 0 ||
                strncmp(line, "SwapFree:", 9) == 0 ||
                strncmp(line, "Cached:", 7) == 0) {
                printf("%s", line);
                count++;
            }
        }
        fclose(meminfo);
    } else {
        printf("无法读取系统内存信息\n");
    }
    printf("\n");
}

// 执行内存锁定
int perform_memory_lock(const struct lock_config *config) {
    int flags = 0;
    
    if (config->lock_current) {
        flags |= MCL_CURRENT;
    }
    if (config->lock_future) {
        flags |= MCL_FUTURE;
    }
    
    if (flags == 0) {
        printf("未指定锁定选项\n");
        return -1;
    }
    
    if (config->verbose) {
        printf("执行内存锁定: ");
        if (config->lock_current) printf("当前内存 ");
        if (config->lock_future) printf("未来内存 ");
        printf("\n");
    }
    
    if (mlockall(flags) == 0) {
        printf("✓ 内存锁定成功\n");
        return 0;
    } else {
        switch (errno) {
            case EPERM:
                printf("✗ 权限不足: 需要 root 权限或 CAP_IPC_LOCK 能力\n");
                break;
            case ENOMEM:
                printf("✗ 内存不足: 超出锁定限制\n");
                break;
            case EINVAL:
                printf("✗ 无效参数\n");
                break;
            default:
                printf("✗ 锁定失败: %s\n", strerror(errno));
                break;
        }
        return -1;
    }
}

// 执行内存解锁
int perform_memory_unlock(const struct lock_config *config) {
    if (config->verbose) {
        printf("执行内存解锁\n");
    }
    
    if (munlockall() == 0) {
        printf("✓ 内存解锁成功\n");
        return 0;
    } else {
        printf("✗ 解锁失败: %s\n", strerror(errno));
        return -1;
    }
}

// 分配测试内存
void* allocate_test_memory(size_t size_mb) {
    size_t size_bytes = size_mb * 1024 * 1024;
    void *buffer = malloc(size_bytes);
    
    if (buffer) {
        printf("分配测试内存: %zu MB\n", size_mb);
        
        // 初始化内存
        memset(buffer, 0xAA, size_bytes);
        printf("内存初始化完成\n");
    } else {
        printf("内存分配失败: %s\n", strerror(errno));
    }
    
    return buffer;
}

// 显示帮助信息
void show_help(const char *program_name) {
    printf("用法: %s [选项]\n", program_name);
    printf("\n选项:\n");
    printf("  -c, --current          锁定当前内存\n");
    printf("  -f, --future           锁定未来内存\n");
    printf("  -u, --unlock           解锁所有内存\n");
    printf("  -s, --status           显示内存状态\n");
    printf("  -l, --limits           显示锁定限制\n");
    printf("  -m, --memory=SIZE      分配测试内存 (MB)\n");
    printf("  -v, --verbose          显示详细信息\n");
    printf("  -h, --help             显示此帮助信息\n");
    printf("\n示例:\n");
    printf("  %s -c -f                  # 锁定当前和未来内存\n", program_name);
    printf("  %s -u                     # 解锁所有内存\n", program_name);
    printf("  %s -s -l                  # 显示状态和限制\n", program_name);
    printf("  %s -c -f -m 100           # 锁定内存并分配 100MB 测试内存\n", program_name);
    printf("  %s --status --verbose     # 详细显示内存状态\n", program_name);
}

int main(int argc, char *argv[]) {
    struct lock_config config = {
        .lock_current = 0,
        .lock_future = 0,
        .unlock_all = 0,
        .show_status = 0,
        .verbose = 0,
        .test_memory = 0
    };
    
    printf("=== 内存锁定管理工具 ===\n\n");
    
    // 解析命令行参数
    static struct option long_options[] = {
        {"current", no_argument,       0, 'c'},
        {"future",  no_argument,       0, 'f'},
        {"unlock",  no_argument,       0, 'u'},
        {"status",  no_argument,       0, 's'},
        {"limits",  no_argument,       0, 'l'},
        {"memory",  required_argument, 0, 'm'},
        {"verbose", no_argument,       0, 'v'},
        {"help",    no_argument,       0, 'h'},
        {0, 0, 0, 0}
    };
    
    int opt;
    while ((opt = getopt_long(argc, argv, "cfuslm:vh", long_options, NULL)) != -1) {
        switch (opt) {
            case 'c':
                config.lock_current = 1;
                break;
            case 'f':
                config.lock_future = 1;
                break;
            case 'u':
                config.unlock_all = 1;
                break;
            case 's':
                config.show_status = 1;
                break;
            case 'l':
                show_lock_limits();
                return 0;
            case 'm':
                config.test_memory = strtoul(optarg, NULL, 10);
                break;
            case 'v':
                config.verbose = 1;
                break;
            case 'h':
                show_help(argv[0]);
                return 0;
            default:
                fprintf(stderr, "使用 '%s --help' 查看帮助信息\n", argv[0]);
                return 1;
        }
    }
    
    // 如果没有指定任何操作,显示帮助
    if (!config.lock_current && !config.lock_future && 
        !config.unlock_all && !config.show_status) {
        show_help(argv[0]);
        return 0;
    }
    
    // 显示初始状态
    if (config.verbose || config.show_status) {
        show_process_memory_status();
        show_system_memory_info();
    }
    
    // 分配测试内存
    void *test_buffer = NULL;
    if (config.test_memory > 0) {
        test_buffer = allocate_test_memory(config.test_memory);
        if (!test_buffer) {
            return 1;
        }
    }
    
    // 执行内存操作
    int result = 0;
    
    if (config.unlock_all) {
        result = perform_memory_unlock(&config);
    } else if (config.lock_current || config.lock_future) {
        result = perform_memory_lock(&config);
    }
    
    // 显示操作后状态
    if (config.show_status) {
        printf("=== 操作后状态 ===\n");
        show_process_memory_status();
    }
    
    // 清理测试内存
    if (test_buffer) {
        free(test_buffer);
        printf("测试内存已释放\n");
    }
    
    // 显示使用建议
    if (result == 0 && (config.lock_current || config.lock_future)) {
        printf("\n=== 使用建议 ===\n");
        printf("内存锁定应用场景:\n");
        printf("1. 实时系统: 防止页面交换导致的延迟\n");
        printf("2. 高频交易: 确保确定性的响应时间\n");
        printf("3. 音频处理: 避免音频断续\n");
        printf("4. 关键应用: 保证内存始终在物理内存中\n");
        printf("\n");
        printf("注意事项:\n");
        printf("1. 需要 root 权限或 CAP_IPC_LOCK 能力\n");
        printf("2. 过度使用可能导致系统内存不足\n");
        printf("3. 应该在应用结束时调用 munlockall()\n");
        printf("4. 可以通过 ulimit -l 调整锁定限制\n");
    }
    
    return result;
}

编译和运行说明 Link to heading

# 编译示例程序
gcc -o mlockall_example1 example1.c -lpthread
gcc -o mlockall_example2 example2.c -lpthread
gcc -o mlockall_example3 example3.c -lpthread

# 运行示例
./mlockall_example1
./mlockall_example2
./mlockall_example3 --help

# 需要权限的操作(使用 sudo)
sudo ./mlockall_example3 -c -f
sudo ./mlockall_example3 -u
sudo ./mlockall_example3 -s -l

# 分配测试内存
./mlockall_example3 -c -f -m 50

系统要求检查 Link to heading

# 检查系统支持
grep -i mlock /boot/config-$(uname -r)

# 检查当前内存锁定限制
ulimit -l

# 增加内存锁定限制(需要 root)
sudo ulimit -l unlimited

# 查看系统内存信息
cat /proc/meminfo
free -h

重要注意事项 Link to heading

  1. 权限要求: 通常需要 root 权限或 CAP_IPC_LOCK 能力
  2. 资源限制: 受 RLIMIT_MEMLOCK 限制
  3. 内存压力: 过度使用可能导致系统内存不足
  4. 性能影响: 锁定大量内存可能影响其他进程
  5. 清理责任: 应该在应用结束时解锁内存

实际应用场景 Link to heading

  1. 实时系统: 音频/视频处理应用
  2. 高频交易: 金融交易系统
  3. 游戏引擎: 对延迟敏感的游戏
  4. 数据库系统: 关键数据库操作
  5. 科学计算: 大规模数值计算
  6. 嵌入式系统: 资源受限的实时应用

最佳实践 Link to heading

// 安全的内存锁定函数
int safe_mlockall(int flags) {
    // 检查参数
    if (flags == 0) {
        errno = EINVAL;
        return -1;
    }
    
    // 检查权限
    if (!(flags & (MCL_CURRENT | MCL_FUTURE))) {
        errno = EINVAL;
        return -1;
    }
    
    // 执行锁定
    int result = mlockall(flags);
    
    // 处理常见错误
    if (result == -1) {
        switch (errno) {
            case EPERM:
                fprintf(stderr, "警告: 权限不足,内存可能被交换\n");
                break;
            case ENOMEM:
                fprintf(stderr, "警告: 内存不足,部分页面可能未锁定\n");
                break;
        }
    }
    
    return result;
}

// 设置适当的内存锁定限制
int set_appropriate_limits() {
    struct rlimit limit;
    
    // 获取当前限制
    if (getrlimit(RLIMIT_MEMLOCK, &limit) == 0) {
        // 如果是普通用户且限制较小,尝试设置合理值
        if (getuid() != 0 && limit.rlim_cur < 64 * 1024 * 1024) {
            limit.rlim_cur = 64 * 1024 * 1024;  // 64MB
            if (limit.rlim_cur > limit.rlim_max) {
                limit.rlim_cur = limit.rlim_max;
            }
            return setrlimit(RLIMIT_MEMLOCK, &limit);
        }
    }
    
    return 0;
}

// 应用程序内存锁定管理
int setup_memory_locking() {
    // 设置限制
    if (set_appropriate_limits() == -1) {
        perror("设置内存限制失败");
    }
    
    // 锁定内存
    if (safe_mlockall(MCL_CURRENT | MCL_FUTURE) == 0) {
        printf("内存锁定已启用\n");
        return 0;
    } else {
        printf("内存锁定失败: %s\n", strerror(errno));
        return -1;
    }
}

// 清理函数
void cleanup_memory_locking() {
    if (munlockall() == 0) {
        printf("内存锁定已释放\n");
    } else {
        perror("释放内存锁定失败");
    }
}

这些示例展示了 mlockall 函数的各种使用方法,从基础的内存锁定到完整的管理工具,帮助你全面掌握 Linux 系统中的内存锁定机制。