munlock 和 munlockall 函数详解 Link to heading

1. 函数介绍 Link to heading

munlockmunlockall 是 Linux 系统中用于解锁内存页面的系统调用,它们是 mlockmlockall 的对应函数。可以把它们想象成"内存保护盾的解除器"——mlock/mlockall 给内存加上保护盾防止被交换,而 munlock/munlockall 则是移除这些保护盾。

在实时系统或对性能要求极高的应用中,内存锁定可以确保关键数据始终驻留在物理内存中。但当不再需要这种保护时,应该使用 munlockmunlockall 来释放资源,让系统可以正常管理内存。

2. 函数原型 Link to heading

#include <sys/mman.h>

int munlock(const void *addr, size_t len);
int munlockall(void);

3. 功能 Link to heading

  • munlock: 解锁指定内存区域的页面,允许它们被交换到磁盘
  • munlockall: 解锁进程的所有内存页面,允许所有页面被交换

4. 参数 Link to heading

munlock 参数 Link to heading

  • addr: 要解锁的内存区域起始地址
  • len: 要解锁的内存区域长度(以字节为单位)

munlockall 参数 Link to heading

  • 无参数,解锁进程的所有内存页面

5. 返回值 Link to heading

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

6. 常见错误码 Link to heading

  • EPERM: 权限不足
  • EINVAL: 参数无效(地址未对齐或长度为0)
  • ENOMEM: 地址范围无效
  • ENOSYS: 系统不支持内存锁定

7. 相关函数 Link to heading

  • mlock: 锁定指定内存区域
  • mlockall: 锁定所有内存页面
  • mlock2: 带扩展选项的内存锁定(Linux 4.4+)
  • getrlimit/setrlimit: 获取/设置资源限制

8. 示例代码 Link to heading

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

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

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

// 分配并锁定内存
void* allocate_and_lock_memory(size_t size_mb) {
    size_t size_bytes = size_mb * 1024 * 1024;
    
    // 分配内存
    void *buffer = malloc(size_bytes);
    if (!buffer) {
        perror("内存分配失败");
        return NULL;
    }
    
    printf("分配内存: %zu MB (%p)\n", size_mb, buffer);
    
    // 初始化内存
    printf("初始化内存...\n");
    memset(buffer, 0xAA, size_bytes);
    
    // 尝试锁定内存
    printf("尝试锁定内存...\n");
    if (mlock(buffer, size_bytes) == 0) {
        printf("✓ 内存锁定成功\n");
    } else {
        if (errno == EPERM) {
            printf("⚠ 权限不足: 需要 root 权限或 CAP_IPC_LOCK 能力\n");
        } else {
            printf("✗ 内存锁定失败: %s\n", strerror(errno));
        }
    }
    
    return buffer;
}

int main() {
    printf("=== munlock 基础示例 ===\n\n");
    
    // 显示系统信息
    show_memory_lock_limits();
    
    // 1. 分配并锁定内存
    printf("1. 分配并锁定内存:\n");
    void *memory_block = allocate_and_lock_memory(10);  // 10MB
    if (!memory_block) {
        return 1;
    }
    
    // 2. 使用锁定的内存
    printf("\n2. 使用锁定的内存:\n");
    for (size_t i = 0; i < 10 * 1024 * 1024; i += 4096) {
        ((char*)memory_block)[i] = (char)(i % 256);
    }
    printf("✓ 内存使用完成\n");
    
    // 3. 解锁部分内存
    printf("\n3. 解锁部分内存 (前 5MB):\n");
    size_t unlock_size = 5 * 1024 * 1024;
    if (munlock(memory_block, unlock_size) == 0) {
        printf("✓ 成功解锁前 %zu MB 内存\n", unlock_size / (1024 * 1024));
    } else {
        printf("✗ 解锁失败: %s\n", strerror(errno));
    }
    
    // 4. 解锁剩余内存
    printf("\n4. 解锁剩余内存:\n");
    void *remaining_addr = (char*)memory_block + unlock_size;
    size_t remaining_size = 10 * 1024 * 1024 - unlock_size;
    
    if (munlock(remaining_addr, remaining_size) == 0) {
        printf("✓ 成功解锁剩余 %zu MB 内存\n", remaining_size / (1024 * 1024));
    } else {
        printf("✗ 解锁失败: %s\n", strerror(errno));
    }
    
    // 5. 重新锁定并使用 munlockall
    printf("\n5. 重新锁定并使用 munlockall:\n");
    if (mlock(memory_block, 10 * 1024 * 1024) == 0) {
        printf("✓ 重新锁定内存成功\n");
        
        // 使用 munlockall 解锁所有内存
        if (munlockall() == 0) {
            printf("✓ munlockall 成功解锁所有内存\n");
        } else {
            printf("✗ munlockall 失败: %s\n", strerror(errno));
        }
    }
    
    // 6. 清理资源
    printf("\n6. 清理资源:\n");
    free(memory_block);
    printf("✓ 内存已释放\n");
    
    printf("\n=== 说明 ===\n");
    printf("1. munlock: 解锁指定内存区域\n");
    printf("2. munlockall: 解锁所有内存页面\n");
    printf("3. 解锁后的内存可以被交换到磁盘\n");
    printf("4. 解锁操作不需要特殊权限\n");
    printf("5. 应该在不需要内存锁定时及时解锁\n");
    
    return 0;
}

示例2:内存锁定管理器 Link to heading

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

// 内存块结构体
struct memory_block {
    void *addr;
    size_t size;
    int is_locked;
    char name[64];
};

// 全局内存块数组
#define MAX_BLOCKS 10
struct memory_block memory_blocks[MAX_BLOCKS];
int block_count = 0;
pthread_mutex_t blocks_mutex = PTHREAD_MUTEX_INITIALIZER;

// 信号处理标志
volatile sig_atomic_t running = 1;

// 信号处理函数
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);  // 终止信号
}

// 创建并锁定内存块
int create_locked_memory_block(const char *name, size_t size_mb) {
    pthread_mutex_lock(&blocks_mutex);
    
    if (block_count >= MAX_BLOCKS) {
        pthread_mutex_unlock(&blocks_mutex);
        fprintf(stderr, "内存块数量已达上限\n");
        return -1;
    }
    
    size_t size_bytes = size_mb * 1024 * 1024;
    void *buffer = malloc(size_bytes);
    
    if (!buffer) {
        pthread_mutex_unlock(&blocks_mutex);
        perror("内存分配失败");
        return -1;
    }
    
    // 初始化内存
    memset(buffer, 0, size_bytes);
    
    // 尝试锁定内存
    int lock_result = mlock(buffer, size_bytes);
    
    // 记录内存块信息
    struct memory_block *block = &memory_blocks[block_count];
    block->addr = buffer;
    block->size = size_bytes;
    block->is_locked = (lock_result == 0);
    strncpy(block->name, name, sizeof(block->name) - 1);
    block->name[sizeof(block->name) - 1] = '\0';
    
    block_count++;
    pthread_mutex_unlock(&blocks_mutex);
    
    printf("创建内存块: %s (%zu MB) - %s\n", 
           name, size_mb, lock_result == 0 ? "已锁定" : "锁定失败");
    
    return block_count - 1;
}

// 解锁指定内存块
int unlock_memory_block(int index) {
    pthread_mutex_lock(&blocks_mutex);
    
    if (index < 0 || index >= block_count) {
        pthread_mutex_unlock(&blocks_mutex);
        fprintf(stderr, "无效的内存块索引: %d\n", index);
        return -1;
    }
    
    struct memory_block *block = &memory_blocks[index];
    
    if (block->is_locked) {
        if (munlock(block->addr, block->size) == 0) {
            block->is_locked = 0;
            printf("解锁内存块: %s (%.2f MB)\n", 
                   block->name, (double)block->size / (1024 * 1024));
            pthread_mutex_unlock(&blocks_mutex);
            return 0;
        } else {
            printf("解锁失败: %s - %s\n", block->name, strerror(errno));
            pthread_mutex_unlock(&blocks_mutex);
            return -1;
        }
    } else {
        printf("内存块 %s 未被锁定\n", block->name);
        pthread_mutex_unlock(&blocks_mutex);
        return 0;
    }
}

// 解锁所有内存块
void unlock_all_memory_blocks() {
    pthread_mutex_lock(&blocks_mutex);
    
    printf("解锁所有内存块:\n");
    for (int i = 0; i < block_count; i++) {
        struct memory_block *block = &memory_blocks[i];
        if (block->is_locked) {
            if (munlock(block->addr, block->size) == 0) {
                block->is_locked = 0;
                printf("  ✓ %s (%.2f MB)\n", 
                       block->name, (double)block->size / (1024 * 1024));
            } else {
                printf("  ✗ %s - %s\n", block->name, strerror(errno));
            }
        } else {
            printf("  ○ %s (未锁定)\n", block->name);
        }
    }
    
    pthread_mutex_unlock(&blocks_mutex);
}

// 显示内存块状态
void show_memory_blocks_status() {
    pthread_mutex_lock(&blocks_mutex);
    
    printf("=== 内存块状态 ===\n");
    if (block_count == 0) {
        printf("没有内存块\n");
    } else {
        for (int i = 0; i < block_count; i++) {
            struct memory_block *block = &memory_blocks[i];
            printf("块 %d: %s\n", i, block->name);
            printf("  地址: %p\n", block->addr);
            printf("  大小: %.2f MB\n", (double)block->size / (1024 * 1024));
            printf("  状态: %s\n", block->is_locked ? "已锁定" : "未锁定");
            printf("\n");
        }
    }
    
    pthread_mutex_unlock(&blocks_mutex);
}

// 清理所有内存块
void cleanup_all_memory_blocks() {
    pthread_mutex_lock(&blocks_mutex);
    
    printf("清理所有内存块:\n");
    for (int i = 0; i < block_count; i++) {
        struct memory_block *block = &memory_blocks[i];
        
        // 如果仍被锁定,先解锁
        if (block->is_locked) {
            if (munlock(block->addr, block->size) == 0) {
                printf("  ✓ 解锁 %s\n", block->name);
            } else {
                printf("  ✗ 解锁 %s 失败: %s\n", block->name, strerror(errno));
            }
        }
        
        // 释放内存
        free(block->addr);
        printf("  ✓ 释放 %s\n", block->name);
    }
    
    block_count = 0;
    pthread_mutex_unlock(&blocks_mutex);
}

// 模拟内存使用的工作线程
void* worker_thread(void* arg) {
    int block_index = *(int*)arg;
    
    pthread_mutex_lock(&blocks_mutex);
    if (block_index >= 0 && block_index < block_count) {
        struct memory_block *block = &memory_blocks[block_index];
        printf("工作线程开始使用内存块: %s\n", block->name);
        pthread_mutex_unlock(&blocks_mutex);
        
        // 在内存块中进行一些操作
        char *buffer = (char*)block->addr;
        size_t chunk_size = block->size / 100;
        
        for (int i = 0; running && i < 100; i++) {
            // 写入数据
            for (size_t j = 0; j < chunk_size && (i * chunk_size + j) < block->size; j++) {
                buffer[i * chunk_size + j] = (char)((i + j) % 256);
            }
            
            // 读取数据
            volatile long sum = 0;
            for (size_t j = 0; j < chunk_size && (i * chunk_size + j) < block->size; j++) {
                sum += buffer[i * chunk_size + j];
            }
            
            if (i % 20 == 0) {
                printf("线程处理进度: %d%%\n", i);
            }
            
            usleep(50000);  // 50ms
        }
        
        printf("工作线程完成: %s\n", block->name);
    } else {
        pthread_mutex_unlock(&blocks_mutex);
        printf("无效的内存块索引: %d\n", block_index);
    }
    
    return NULL;
}

int main() {
    pthread_t threads[3];
    int thread_indices[3];
    
    printf("=== 内存锁定管理器示例 ===\n\n");
    
    // 设置信号处理
    setup_signal_handlers();
    
    // 显示初始状态
    printf("创建测试内存块:\n");
    
    // 创建多个内存块
    create_locked_memory_block("Critical_Data", 5);    // 5MB 关键数据
    create_locked_memory_block("Cache_Buffer", 10);    // 10MB 缓存
    create_locked_memory_block("Temp_Work", 2);        // 2MB 临时工作区
    
    show_memory_blocks_status();
    
    // 创建工作线程
    printf("创建工作线程...\n");
    for (int i = 0; i < 3; i++) {
        thread_indices[i] = i;
        if (pthread_create(&threads[i], NULL, worker_thread, &thread_indices[i]) != 0) {
            perror("创建线程失败");
            continue;
        }
    }
    
    // 运行一段时间后解锁部分内存
    printf("运行中... (按 Ctrl+C 退出)\n");
    sleep(2);
    
    printf("\n=== 动态内存管理 ===\n");
    
    // 解锁临时工作区
    printf("解锁临时工作区:\n");
    unlock_memory_block(2);  // Temp_Work
    
    show_memory_blocks_status();
    
    sleep(2);
    
    // 再次解锁缓存区
    printf("解锁缓存区:\n");
    unlock_memory_block(1);  // Cache_Buffer
    
    show_memory_blocks_status();
    
    // 等待用户中断或线程完成
    for (int i = 0; i < 3; i++) {
        pthread_join(threads[i], NULL);
    }
    
    // 最终清理
    printf("\n=== 最终清理 ===\n");
    unlock_all_memory_blocks();
    show_memory_blocks_status();
    cleanup_all_memory_blocks();
    
    printf("\n=== 内存锁定管理说明 ===\n");
    printf("最佳实践:\n");
    printf("1. 只锁定真正需要的内存区域\n");
    printf("2. 及时解锁不需要的锁定内存\n");
    printf("3. 避免过度使用内存锁定\n");
    printf("4. 监控内存锁定资源使用情况\n");
    printf("5. 在程序退出时清理所有锁定\n");
    printf("\n");
    printf("munlock 优势:\n");
    printf("1. 精确控制: 可以解锁特定内存区域\n");
    printf("2. 资源管理: 允许系统回收内存资源\n");
    printf("3. 灵活性: 可以部分解锁内存\n");
    printf("4. 无权限要求: 解锁操作不需要特殊权限\n");
    
    return 0;
}

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

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

// 配置结构体
struct unlock_config {
    int unlock_all;         // 解锁所有内存
    int show_status;        // 显示状态
    int verbose;            // 详细输出
    char **addresses;       // 要解锁的地址列表
    size_t *sizes;          // 对应的大小列表
    int addr_count;         // 地址数量
    int test_mode;          // 测试模式
    size_t test_size;       // 测试内存大小
};

// 显示系统内存信息
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 < 8) {
            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 ||
                strncmp(line, "Buffers:", 8) == 0 ||
                strncmp(line, "Active:", 7) == 0) {
                printf("%s", line);
                count++;
            }
        }
        fclose(meminfo);
    }
    
    printf("\n");
}

// 显示内存锁定限制
void show_lock_limits() {
    struct rlimit limit;
    
    printf("=== 内存锁定限制 ===\n");
    if (getrlimit(RLIMIT_MEMLOCK, &limit) == 0) {
        printf("最大可锁定内存:\n");
        if (limit.rlim_cur == RLIM_INFINITY) {
            printf("  软限制: 无限制\n");
        } else {
            printf("  软限制: %lu 字节 (%.2f MB)\n", 
                   (unsigned long)limit.rlim_cur,
                   (double)limit.rlim_cur / (1024 * 1024));
        }
        if (limit.rlim_max == RLIM_INFINITY) {
            printf("  硬限制: 无限制\n");
        } else {
            printf("  硬限制: %lu 字节 (%.2f MB)\n", 
                   (unsigned long)limit.rlim_max,
                   (double)limit.rlim_max / (1024 * 1024));
        }
    }
    printf("\n");
}

// 解析地址字符串
void* parse_address(const char *addr_str) {
    char *endptr;
    unsigned long addr = strtoul(addr_str, &endptr, 16);
    
    if (*endptr != '\0') {
        fprintf(stderr, "无效的地址格式: %s\n", addr_str);
        return NULL;
    }
    
    return (void*)addr;
}

// 解析大小字符串
size_t parse_size(const char *size_str) {
    char *endptr;
    unsigned long size = strtoul(size_str, &endptr, 10);
    
    if (*endptr == 'G' || *endptr == 'g') {
        size *= 1024 * 1024 * 1024;
    } else if (*endptr == 'M' || *endptr == 'm') {
        size *= 1024 * 1024;
    } else if (*endptr == 'K' || *endptr == 'k') {
        size *= 1024;
    }
    
    return (size_t)size;
}

// 执行 munlock 操作
int perform_munlock(void *addr, size_t size, const char *description) {
    if (description) {
        printf("解锁内存区域: %s\n", description);
        printf("  地址: %p\n", addr);
        printf("  大小: %zu 字节 (%.2f MB)\n", size, (double)size / (1024 * 1024));
    }
    
    if (munlock(addr, size) == 0) {
        printf("✓ 解锁成功\n");
        return 0;
    } else {
        printf("✗ 解锁失败: %s\n", strerror(errno));
        return -1;
    }
}

// 执行 munlockall 操作
int perform_munlockall() {
    printf("解锁所有内存页面...\n");
    
    if (munlockall() == 0) {
        printf("✓ 成功解锁所有内存页面\n");
        return 0;
    } else {
        printf("✗ 解锁所有内存页面失败: %s\n", strerror(errno));
        return -1;
    }
}

// 测试模式:分配、锁定、然后解锁内存
int test_mode_operation(size_t size_mb) {
    size_t size_bytes = size_mb * 1024 * 1024;
    
    printf("=== 测试模式 ===\n");
    printf("分配测试内存: %zu MB\n", size_mb);
    
    // 分配内存
    void *buffer = malloc(size_bytes);
    if (!buffer) {
        perror("内存分配失败");
        return -1;
    }
    
    // 初始化内存
    printf("初始化内存...\n");
    memset(buffer, 0xAA, size_bytes);
    
    // 锁定内存
    printf("锁定内存...\n");
    if (mlock(buffer, size_bytes) == 0) {
        printf("✓ 内存锁定成功\n");
    } else {
        printf("✗ 内存锁定失败: %s\n", strerror(errno));
        free(buffer);
        return -1;
    }
    
    // 使用内存
    printf("使用锁定的内存...\n");
    for (size_t i = 0; i < size_bytes; i += 4096) {
        ((char*)buffer)[i] = (char)(i % 256);
    }
    
    // 解锁内存
    printf("解锁内存...\n");
    if (munlock(buffer, size_bytes) == 0) {
        printf("✓ 内存解锁成功\n");
    } else {
        printf("✗ 内存解锁失败: %s\n", strerror(errno));
    }
    
    // 释放内存
    free(buffer);
    printf("✓ 内存已释放\n");
    
    return 0;
}

// 显示帮助信息
void show_help(const char *program_name) {
    printf("用法: %s [选项]\n", program_name);
    printf("\n选项:\n");
    printf("  -a, --all              解锁所有内存页面\n");
    printf("  -s, --status           显示系统内存状态\n");
    printf("  -l, --limits           显示内存锁定限制\n");
    printf("  -u, --unlock=ADDR:SIZE 解锁指定内存区域\n");
    printf("  -t, --test[=SIZE]      测试模式 (默认 10MB)\n");
    printf("  -v, --verbose          详细输出\n");
    printf("  -h, --help             显示此帮助信息\n");
    printf("\n地址格式:\n");
    printf("  地址: 十六进制格式 (如 0x7fff12345678)\n");
    printf("  大小: 数字加单位 (如 1024, 1K, 1M, 1G)\n");
    printf("\n示例:\n");
    printf("  %s -a                           # 解锁所有内存\n", program_name);
    printf("  %s -u 0x7fff12345678:1M         # 解锁指定区域\n", program_name);
    printf("  %s -s -l                        # 显示状态和限制\n", program_name);
    printf("  %s -t 50                        # 测试 50MB 内存\n", program_name);
    printf("  %s --unlock=0x12345678:4K --verbose  # 详细模式\n", program_name);
}

int main(int argc, char *argv[]) {
    struct unlock_config config = {
        .unlock_all = 0,
        .show_status = 0,
        .verbose = 0,
        .addresses = NULL,
        .sizes = NULL,
        .addr_count = 0,
        .test_mode = 0,
        .test_size = 10  // 默认 10MB
    };
    
    printf("=== 内存解锁工具 ===\n\n");
    
    // 解析命令行参数
    static struct option long_options[] = {
        {"all",     no_argument,       0, 'a'},
        {"status",  no_argument,       0, 's'},
        {"limits",  no_argument,       0, 'l'},
        {"unlock",  required_argument, 0, 'u'},
        {"test",    optional_argument, 0, 't'},
        {"verbose", no_argument,       0, 'v'},
        {"help",    no_argument,       0, 'h'},
        {0, 0, 0, 0}
    };
    
    int opt;
    while ((opt = getopt_long(argc, argv, "aslu:t::vh", long_options, NULL)) != -1) {
        switch (opt) {
            case 'a':
                config.unlock_all = 1;
                break;
            case 's':
                config.show_status = 1;
                break;
            case 'l':
                show_lock_limits();
                return 0;
            case 'u': {
                // 解析 ADDR:SIZE 格式
                char *colon = strchr(optarg, ':');
                if (colon) {
                    *colon = '\0';
                    void *addr = parse_address(optarg);
                    size_t size = parse_size(colon + 1);
                    
                    if (addr && size > 0) {
                        config.addresses = realloc(config.addresses, 
                                                  (config.addr_count + 1) * sizeof(void*));
                        config.sizes = realloc(config.sizes, 
                                              (config.addr_count + 1) * sizeof(size_t));
                        
                        config.addresses[config.addr_count] = addr;
                        config.sizes[config.addr_count] = size;
                        config.addr_count++;
                        
                        if (config.verbose) {
                            printf("添加解锁区域: %p - %zu 字节\n", addr, size);
                        }
                    } else {
                        fprintf(stderr, "无效的地址或大小: %s\n", optarg);
                        return 1;
                    }
                } else {
                    fprintf(stderr, "地址格式应为 ADDR:SIZE\n");
                    return 1;
                }
                break;
            }
            case 't':
                config.test_mode = 1;
                if (optarg) {
                    config.test_size = 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.verbose || config.show_status) {
        show_system_memory_info();
        show_lock_limits();
    }
    
    // 测试模式
    if (config.test_mode) {
        if (test_mode_operation(config.test_size) != 0) {
            return 1;
        }
        
        if (!config.unlock_all && config.addr_count == 0) {
            return 0;
        }
    }
    
    // 执行解锁操作
    int result = 0;
    
    if (config.unlock_all) {
        result = perform_munlockall();
    } else if (config.addr_count > 0) {
        for (int i = 0; i < config.addr_count; i++) {
            char description[128];
            snprintf(description, sizeof(description), "区域 %d", i + 1);
            
            if (perform_munlock(config.addresses[i], config.sizes[i], 
                               config.verbose ? description : NULL) != 0) {
                result = -1;
            }
        }
    } else if (!config.show_status && !config.test_mode) {
        // 没有指定操作,显示帮助
        show_help(argv[0]);
        return 0;
    }
    
    // 显示操作后状态
    if (config.show_status) {
        printf("=== 操作后状态 ===\n");
        show_system_memory_info();
    }
    
    // 清理资源
    if (config.addresses) {
        free(config.addresses);
    }
    if (config.sizes) {
        free(config.sizes);
    }
    
    // 显示使用建议
    printf("\n=== 内存解锁使用建议 ===\n");
    printf("适用场景:\n");
    printf("1. 实时应用结束后释放锁定内存\n");
    printf("2. 内存压力大时释放不必要的锁定\n");
    printf("3. 程序退出前清理资源\n");
    printf("4. 动态调整内存锁定策略\n");
    printf("\n");
    printf("最佳实践:\n");
    printf("1. 及时解锁不需要的锁定内存\n");
    printf("2. 避免内存锁定泄漏\n");
    printf("3. 监控系统内存使用情况\n");
    printf("4. 在异常处理中包含解锁操作\n");
    printf("5. 使用 munlockall 简化清理工作\n");
    printf("\n");
    printf("注意事项:\n");
    printf("1. munlock 操作不需要特殊权限\n");
    printf("2. 解锁已解锁的内存不会出错\n");
    printf("3. munlockall 会解锁进程的所有内存\n");
    printf("4. 应该在程序结束时调用 munlockall\n");
    
    return (result == 0) ? 0 : 1;
}

编译和运行说明 Link to heading

# 编译示例程序
gcc -o munlock_example1 example1.c
gcc -o munlock_example2 example2.c -lpthread
gcc -o munlock_example3 example3.c -lpthread

# 运行示例
./munlock_example1
./munlock_example2
./munlock_example3 --help

# 基本操作
./munlock_example3 -s
./munlock_example3 -a
./munlock_example3 -t 20

# 需要权限的测试(使用 sudo)
sudo ./munlock_example3 -t 100

系统要求检查 Link to heading

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

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

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

# 检查当前进程的内存锁定状态
cat /proc/self/status | grep -i vmlck

重要注意事项 Link to heading

  1. 权限要求: munlockmunlockall 不需要特殊权限
  2. 错误处理: 解锁已解锁的内存不会出错
  3. 资源管理: 应该及时解锁不需要的锁定内存
  4. 清理责任: 程序结束时应该调用 munlockall
  5. 内存释放: 解锁后仍需 free 释放内存

实际应用场景 Link to heading

  1. 实时系统: 应用结束时释放锁定内存
  2. 高性能计算: 动态调整内存锁定策略
  3. 游戏引擎: 资源管理优化
  4. 数据库系统: 内存管理优化
  5. 科学计算: 大规模内存操作管理

最佳实践 Link to heading

// 安全的内存解锁函数
int safe_munlock(const void *addr, size_t len) {
    // 验证参数
    if (!addr || len == 0) {
        errno = EINVAL;
        return -1;
    }
    
    // 执行解锁
    int result = munlock(addr, len);
    
    // 处理常见情况
    if (result == -1) {
        switch (errno) {
            case ENOMEM:
                // 地址范围无效,可能已经释放
                fprintf(stderr, "警告: 内存地址范围无效\n");
                break;
            case EINVAL:
                fprintf(stderr, "警告: 无效的地址或长度参数\n");
                break;
        }
    }
    
    return result;
}

// 程序退出时的清理函数
void cleanup_memory_locking() {
    // 解锁所有内存
    if (munlockall() == 0) {
        printf("内存锁定已清理\n");
    } else {
        perror("清理内存锁定失败");
    }
    
    // 可以在这里添加其他清理操作
}

// RAII 风格的内存锁定管理
typedef struct {
    void *addr;
    size_t size;
    int locked;
} memory_lock_t;

int memory_lock_init(memory_lock_t *lock, void *addr, size_t size) {
    lock->addr = addr;
    lock->size = size;
    lock->locked = 0;
    
    if (mlock(addr, size) == 0) {
        lock->locked = 1;
        return 0;
    }
    return -1;
}

void memory_lock_destroy(memory_lock_t *lock) {
    if (lock->locked) {
        munlock(lock->addr, lock->size);
        lock->locked = 0;
    }
}

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