You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在MPI中通过单个进程停止并恢复所有进程?

MPI中实现进程停止与恢复的可行方案(用于协调式Checkpointing)

问题概述

需要实现协调式Checkpointing流程:指定协调进程(进程A)在特定时刻触发所有进程暂停主任务执行,各进程完成Checkpoint后通知协调进程,待全部完成后由协调进程恢复所有进程继续执行,协调进程自身也需完成Checkpoint。

尝试过的方法及问题

尝试用kill(pid, SIGSTOP)和kill(pid, SIGCONT)实现,但需要收集所有进程的PID。最初用全局std::vector收集PID失败——由于MPI进程是独立运行的,全局变量不会跨进程共享,仅能收集到协调进程自身的PID。

推荐解决方案:协作式暂停恢复(符合MPI规范)

MPI不推荐直接用信号强制暂停进程(可能破坏MPI内部通信状态),更可靠的方式是通过MPI通信让进程主动进入暂停/恢复状态,示例代码如下:

#include <stdio.h>
#include <mpi.h>
#include <unistd.h>

#define TAG_PAUSE 10
#define TAG_RESUME 11

int main(int argc, char **argv) 
{
    int num_procs, my_rank, my_id;
    
    MPI_Init(&argc, &argv);
    MPI_Comm_rank(MPI_COMM_WORLD, &my_rank);
    MPI_Comm_size(MPI_COMM_WORLD, &num_procs);
    
    my_id = getpid();
    printf("Hello! I'm process with rank %i out of %i processes and my id is %i\n", 
           my_rank, num_procs, my_id);

    // 以rank0作为协调进程(进程A)
    if (my_rank == 0) {
        // 向所有其他进程发送暂停命令
        for (int i = 1; i < num_procs; i++) {
            MPI_Send(NULL, 0, MPI_INT, i, TAG_PAUSE, MPI_COMM_WORLD);
        }
        // 协调进程执行自身Checkpoint
        printf("Rank 0: Starting checkpoint...\n");
        usleep(1000000); // 模拟Checkpoint耗时
        printf("Rank 0: Checkpoint completed.\n");

        // 等待所有进程完成Checkpoint(用MPI_Barrier简化实现,实际可自定义消息通知)
        printf("Rank 0: Waiting for all processes to finish checkpoint...\n");
        MPI_Barrier(MPI_COMM_WORLD);

        // 向所有进程发送恢复命令
        for (int i = 1; i < num_procs; i++) {
            MPI_Send(NULL, 0, MPI_INT, i, TAG_RESUME, MPI_COMM_WORLD);
        }
    } else {
        // 非协调进程等待暂停命令
        MPI_Recv(NULL, 0, MPI_INT, 0, TAG_PAUSE, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
        printf("Rank %i: Paused, starting checkpoint...\n", my_rank);
        // 执行Checkpoint操作
        usleep(2000000); // 模拟不同进程的Checkpoint耗时
        printf("Rank %i: Checkpoint completed.\n", my_rank);
        // 通知协调进程完成(通过Barrier同步)
        MPI_Barrier(MPI_COMM_WORLD);
        // 等待恢复命令
        MPI_Recv(NULL, 0, MPI_INT, 0, TAG_RESUME, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
    }

    printf("Bye! I'm process %i out of %i processes and my id is %i\n", 
           my_rank, num_procs, my_id);
    
    MPI_Finalize();
    return 0;
}

方案说明

  • 协调进程通过MPI_Send发送暂停/恢复命令,各进程主动响应,避免强制信号带来的风险。
  • 用MPI_Barrier实现Checkpoint完成的同步,实际场景中也可以用MPI_Gather或自定义消息实现更精细的状态跟踪。
  • 所有进程在可控的状态下进入暂停,不会打断MPI内部操作,保证了程序的稳定性。

备选方案:基于信号的实现(不推荐)

如果必须使用信号,需先通过MPI通信正确收集所有进程的PID,示例代码如下:

#include <stdio.h>
#include <mpi.h>
#include <unistd.h>
#include <signal.h>
#include <stdlib.h>

int main(int argc, char **argv) 
{
    int num_procs, my_rank, my_id;
    int *all_pids = NULL;
    
    MPI_Init(&argc, &argv);
    MPI_Comm_rank(MPI_COMM_WORLD, &my_rank);
    MPI_Comm_size(MPI_COMM_WORLD, &num_procs);
    
    my_id = getpid();
    printf("Hello! I'm process with rank %i out of %i processes and my id is %i\n", 
           my_rank, num_procs, my_id);

    // 收集所有进程PID到协调进程(rank0)
    if (my_rank == 0) {
        all_pids = (int*)malloc(num_procs * sizeof(int));
    }
    MPI_Gather(&my_id, 1, MPI_INT, all_pids, 1, MPI_INT, 0, MPI_COMM_WORLD);

    if (my_rank == 0) {
        printf("Rank 0: Pausing all processes...\n");
        // 先暂停其他进程,协调进程完成自身Checkpoint后再暂停自己(避免自己提前暂停无法后续恢复)
        for (int i = 1; i < num_procs; i++) {
            kill(all_pids[i], SIGSTOP);
        }
        // 协调进程执行Checkpoint
        usleep(3000000);
        printf("Rank 0: Resuming all processes...\n");
        // 恢复所有进程
        for (int i = 0; i < num_procs; i++) {
            kill(all_pids[i], SIGCONT);
        }
        free(all_pids);
    } else {
        // 非协调进程执行主任务,等待被信号暂停
        usleep(1000000);
    }

    printf("Bye! I'm process %i out of %i processes and my id is %i\n", 
           my_rank, num_procs, my_id);
    
    MPI_Finalize();
    return 0;
}

注意事项

  • 强烈不推荐此方案:MPI进程被强制信号暂停时,若正处于MPI通信操作中,可能导致死锁、数据损坏或MPI运行时异常。
  • 需严格控制信号发送时机,确保进程不在MPI关键操作中被暂停。

内容的提问来源于stack exchange,提问作者Coder

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.18 01:50:25