OpenMPI多进程场景下printf未等待scanf按序执行的问题
问题根因
- MPI运行时默认仅将终端标准输入绑定到
Rank 0进程,其余进程的标准输入默认被重定向到空设备,因此你只能触发一次输入操作,且输入的内容仅能被Rank 0获取。 - 无同步逻辑时多进程的执行顺序由操作系统调度决定,因此所有进程的
printf会先被调度执行完成,才会执行Rank 0的scanf逻辑。
实现方案
要实现按Rank顺序依次打印+输入,需要两点:1. 增加进程同步逻辑,保证按Rank 0到Rank N-1的顺序串行执行打印、输入流程;2. 输入统一由Rank 0读取后,分发到对应进程。
修改后的代码如下:
#include <stdio.h> #include <mpi.h> int main(int argc, char *argv[]) { int rank, size; MPI_Init(&argc, &argv); MPI_Comm_rank(MPI_COMM_WORLD, &rank); MPI_Comm_size(MPI_COMM_WORLD, &size); int x; // 按Rank顺序逐个执行打印、输入逻辑 for (int i = 0; i < size; i++) { // 同步所有进程,确保上一个进程的操作完全完成 MPI_Barrier(MPI_COMM_WORLD); if (rank == i) { // 只有当前轮到的进程打印Rank号 printf("Rank: %d\n", rank); fflush(stdout); } // 再次同步,确保打印完成再处理输入 MPI_Barrier(MPI_COMM_WORLD); if (rank == 0) { // 只有Rank 0负责读入输入 int input; scanf("%d", &input); // 把输入发送给当前轮到的进程 if (i == 0) { x = input; } else { MPI_Send(&input, 1, MPI_INT, i, 0, MPI_COMM_WORLD); } } else if (rank == i) { // 非0的当前进程接收Rank 0发来的输入值 MPI_Recv(&x, 1, MPI_INT, 0, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE); } } // 可放开下方注释验证每个进程拿到的数值是否正确 // MPI_Barrier(MPI_COMM_WORLD); // printf("Rank %d got x = %d\n", rank, x); MPI_Finalize(); return 0; }
运行效果说明
编译运行后就会匹配你预期的逻辑:先打印Rank: 0,等待输入一个数后,再打印Rank: 1,再等待输入下一个数,依次类推,每个进程最终都会拿到对应输入的数值。
内容的提问来源于stack exchange,提问作者Era Freddy
相关产品推荐
相关产品推荐

