能否为MPI行通信子内的进程使用shmget创建共享内存?
能否用shmget()为MPI行通信子内的进程创建共享内存?
shmget函数用于基于键值创建新共享内存段或查找现有共享内存段,共享内存段是可被多个进程共享的内存区域。目前已通过MPI_Comm_split创建了行通信子,计划使用shmget而非MPI_win_allocate函数,想问是否可行?
核心结论
可以,但有严格的前提条件和需要注意的实现细节:
前提条件
行通信子内的所有进程必须运行在同一物理节点上。因为shmget属于System V共享内存机制,仅支持同一节点内的进程共享,跨节点进程无法通过该方式访问共享内存。
实现步骤
- 指定创建者:选择行通信子内的某一个进程(比如rank为0的进程)作为共享内存的创建者,调用
shmget()创建内存段。可以选择IPC_PRIVATE作为键值(仅能通过传递shmid共享,避免键冲突),或者用ftok()生成唯一自定义键。 - 传递共享内存标识符:创建者通过MPI通信(比如
MPI_Bcast)将生成的shmid发送给行通信子内的所有其他进程。 - 映射内存段:所有进程调用
shmat()将共享内存段映射到自身的地址空间,之后即可像访问普通内存一样操作该区域。 - 清理资源:使用完毕后,所有进程调用
shmdt()解除内存映射,最后由创建者调用shmctl()删除共享内存段。
关键注意事项
- 同步机制:shmget不提供进程间同步,需要自行通过System V信号量(
semget())或MPI同步操作(比如MPI_Barrier)保证内存访问的有序性,避免竞态条件。 - 权限设置:调用shmget时需设置正确的权限位(如
0666),确保行通信子内所有进程都能访问该共享内存段。 - 键值冲突:如果使用自定义键,务必保证键值全局唯一,避免与系统中其他共享内存段冲突。
已实现的MPI行通信子代码
// 获取原始通信子中的进程rank和总数量 int world_rank, world_size; MPI_Comm_rank(MPI_COMM_WORLD, &world_rank); MPI_Comm_size(MPI_COMM_WORLD, &world_size); int color = world_rank / 4; // 根据进程所在行确定color值 // 根据color拆分通信子,用原始rank排序 MPI_Comm row_comm; MPI_Comm_split(MPI_COMM_WORLD, color, world_rank, &row_comm); int row_rank, row_size; MPI_Comm_rank(row_comm, &row_rank); MPI_Comm_size(row_comm, &row_size); printf("全局进程RANK/SIZE: %d/%d \t 行通信子RANK/SIZE: %d/%d\n", world_rank, world_size, row_rank, row_size); MPI_Comm_free(&row_comm);
内容的提问来源于stack exchange,提问作者Ishan
相关产品推荐
相关产品推荐

