---
title: kupl_shm_attach
description: "申请内存，并将申请的内存与另一进程的内存进行映射，实现共享内存的目的。"
url: https://www.hikunpeng.com/document/detail/zh/kunpenghpcs/hpckit/devg/KunpengHPCKit_developer_229.html
sourcePath: /source/zh/kunpenghpcs/hpckit/devg/KunpengHPCKit_developer_229.html
indexId: c4d77886ea93a397953739a36a36c8b7f3531b701a9aa19d652cd6915e19ebc567
---
# kupl_shm_attach

申请内存，并将申请的内存与另一进程的内存进行映射，实现共享内存的目的。

#### 接口定义

void* kupl_shm_attach(struct kupl_shm_addr_t addr, size_t size)


#### 参数


**表1 参数定义**

| 参数名 | 类型 | 描述 | 输入/输出 |
| --- | --- | --- | --- |
| addr | struct kupl\_shm\_addr\_t | 需要映射的内存信息 | 输入 |
| size | size\_t | 需要映射的内存大小 | 输入 |


**表2 映射内存信息结构体kupl_shm_addr_t定义**

| 参数名 | 类型 | 描述 | 输入/输出 |
| --- | --- | --- | --- |
| src\_addr | void\* | 需要映射的内存的虚拟地址 | 输入 |
| src\_pid | int | 需要映射的内存所在的进程的进程号 | 输入 |
| dst\_pid | int | 本进程的进程号 | 输入 |


#### 返回值

- 成功：返回本进程申请并映射成功的内存指针ptr
- 失败：返回nullptr


#### 示例

```
进程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解除绑定并退出。
