kupl_shm_attach
申请内存,并将申请的内存与另一进程的内存进行映射,实现共享内存的目的。
接口定义
void* kupl_shm_attach(struct kupl_shm_addr_t addr, size_t size)
参数
参数名 |
类型 |
描述 |
输入/输出 |
|---|---|---|---|
addr |
struct kupl_shm_addr_t |
需要映射的内存信息 |
输入 |
size |
size_t |
需要映射的内存大小 |
输入 |
参数名 |
类型 |
描述 |
输入/输出 |
|---|---|---|---|
src_addr |
void* |
需要映射的内存的虚拟地址 |
输入 |
src_pid |
int |
需要映射的内存所在的进程的进程号 |
输入 |
dst_pid |
int |
本进程的进程号 |
输入 |
返回值
- 成功:返回本进程申请并映射成功的内存指针ptr
- 失败:返回nullptr
示例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 | 进程A #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <sys/mman.h> #include <sys/stat.h> #include <fcntl.h> #include <string.h> #include "kupl.h" #define SHM_NAME "/pid_shm_example" typedef struct { pid_t pid; int ready; void* addr; } shared_data_t; int main() { // 创建共享内存对象、填入数据 int shm_fd = shm_open(SHM_NAME, O_CREAT | O_RDWR, 0666); ftruncate(shm_fd, sizeof(shared_data_t); shared_data_t *shared_data = mmap(NULL, sizeof(shared_data_t), PROT_READ | PROT_WRITE, MAP_SHARED, shm_fd, 0); // 写入PID到共享内存 shared_data->pid = getpid(); printf("Process A: PID %d\n", shared_data->pid); shared_data->ready = 1; shared_data->addr = kupl_malloc(KUPL_MEM_DEFAULT, sizeof(shared_data_t)); memset(shared_data->addr, 0, sizeof(shared_data_t)); data_addr->pid = getpid(); // 保持运行,等待进程B读取 printf("Press Enter to exit...\n"); getchar(); // 清理 kupl_free(KUPL_MEM_DEFAULT, shared_data->addr); munmap(shared_data, sizeof(shared_data_t)); shm_unlink(SHM_NAME); return 0; } 进程B #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <sys/mman.h> #include <sys/stat.h> #include <fcntl.h> #include <string.h> #include "kupl.h" #define SHM_NAME "/pid_shm_example" typedef struct { pid_t pid; int ready; void* addr; } shared_data_t; int main() { // 打开共享内存对象 int shm_fd = shm_open(SHM_NAME, O_RDONLY, 0666); shared_data_t *shared_data = mmap(NULL, sizeof(shared_data_t), PROT_READ, MAP_SHARED, shm_fd, 0); shared_data_t *attach_data = (shared_data_t*)calloc(1, sizeof(shared_data_t)); // 等待数据就绪 while (shared_data->ready == 0) { usleep(100000); // 等待100ms } // 读取信息 kupl_shm_addr_t kupl_shm_addr_info; kupl_shm_addr_info.src_addr = shared_data->addr; kupl_shm_addr_info.src_pid = shared_data->pid; kupl_shm_addr_info.dst_pid = getpid(); // 执行映射 attach_data->addr = kupl_shm_attach(kupl_shm_addr_info, sizeof(shared_data_t)); if (attach_data->addr == NULL) { printf("attach wrong!\n"); } else { printf("attach OK!"); } // 等待数据就绪 shared_data_t* data_addr = (shared_data_t*)attach_data->addr; while (data_addr->ready != 3) { usleep(100000); // 等待100ms } printf("Process B: Read PID %d from shared memory\n", data_addr->pid); // 清理 munmap(shared_data, sizeof(shared_data_t)); kupl_shm_detach(attach_data->addr); free(attach_data); close(shm_fd); return 0; } |
运行结果如下。
进程A Process A: PID xxxx Press Enter to exit... 进程B attach OK! Process B: Read PID xxxx from shared memory //应与上文进程A打印的PID一致
上述示例演示了使用kupl_shm_attach的申请内存并将申请的内存与另一进程的内存进行映射,之后解除由kupl_shm_attach接口建立的映射,并释放由kupl_shm_attach申请的内存的流程。在先后运行进程A和进程B的程序后,A进程后申请内存并写入数据。写入完毕后,会保持运行等待B进程读取完毕并在输入任意键后退出;运行B进程后则会调用kupl_shm_attach尝试进行内存映射。内存映射成功后,会开始尝试读取A进程写入的内容,读取到的内容应为A进程的pid。读取完毕后,B进程会调用detach解除绑定并退出。
父主题: 共享内存通信函数