允许任何进程发送退出消息

时间:2013-10-04 01:30:14

标签: c++ c mpi

我在C / C ++ MPI程序中存在一个问题,它模拟在所有进程中玩游戏。如果任何进程获胜,包括master,该进程应告诉所有其他进程退出其游戏,以便结果可以发送给master并由master进行总计。

问题是我有时会在获胜过程中获得一个或多个进程,说他们先赢了。这导致在完成之前长时间悬挂(在某些情况下超过一分钟)。我不确定我是否在所有进程之间正确处理退出消息的情况。

更新:此程序在单台计算机上运行,​​而不是在网络上运行。机器不在互联网上。

更新2 :由于内部游戏代码导致操作过多,我能够大幅减少延迟问题。我仍然在寻找解释我使用Irecv / Isend退出流程的方式。

更新3 :发现我的问题,在我的回答中显示。

以下是我的应用程序中的一些代码来帮助。

int max_streak_length; // set in main from argv[], greater than 0
bool should_quit = false;

void checkMessages()
{
    static int recvFlag
    static bool msgBuff;
    static MPI_Request request;
    MPI_Status status;

    // Are we already listening
    if( request )
    {
        // Test for message
        MPI_Test(&request, &recvFlag, &status);

        if( recvFlag )
        {
            if( status.MPI_TAG == TAG_QUIT )
                should_quit = true;
        }
    }

    // Start listening if we aren't
    if( !request )
        MPI_Irecv(&msgBuff, 1, MPI_C_BOOL, MPI_ANY_SOURCE, TAG_QUIT, MPI_COMM_WORLD, &request);
}

void processMaster(int numProcs) {
    double start = MPI_Wtime();
    Game game(max_streak_length);

    do
    {
        if( numProcs > 1 )
            checkMessages();
        game.play();
    } while( !should_quit && !game.is_game_over() );

    // Let other processes know they should stop, if I won
    if( !should_quit && game.is_game_over() )
    {
        cout << "Master wins " << MPI_Wtime() << endl;
        for( int pID = 1; numProcs > 1 && pID < numProcs; ++pID ) 
        {
            MPI_Request r;
            MPI_Isend(&should_quit, 1, MPI_C_BOOL, pID, TAG_QUIT, MPI_COMM_WORLD, &r);
        }
    }

    cout << "master quitting" << endl;
}

void processSlave(int numProcs, int rank) {
    Game game(max_streak_length);

    do
    {
        checkMessages();
        game.play();
    } while( !should_quit && !game.is_game_over() );

    // Let other processes know they should stop, if I won
    if( !should_quit && game.is_game_over() )
    {
        cout << rank << " wins " << MPI_Wtime() << endl;
        for( int pID = 0; pID < numProcs; ++pID ) 
        {
            if( pID == rank )
                continue;
            MPI_Request r;
            MPI_Isend(&should_quit, 1, MPI_C_BOOL, pID, TAG_QUIT, MPI_COMM_WORLD, &r);
        }
    }

    cout << rank << " quitting" << endl;
}

2 个答案:

答案 0 :(得分:0)

'赢'包的Wireshark / ethereal时间? “赢家”之间有多少延迟? 协议允许多个客户说“赢”,但客户是否认为他们“赢了”,或等待确认?

您的邮件协议是什么?你在几个地方展示'TAG_QUIT'。怎么样,

  • 孩子用'Win'
  • 表示父母
  • 父母通过'确认'
  • 向孩子发出信号
  • 获胜的孩子向其他孩子发出'退出'(幸灾乐祸)的信号
  • 或,父母通过'退出'
  • 向其他孩子发出信号
  • 失去孩子(ren)可能会发出'胜利'(由于种族,延迟而失败)的信号
  • 父母表示失去/迟到的孩子有'失败'或'失败'

答案 1 :(得分:0)

我解决了我的问题。我根本不再得到延迟,问题在于我的游戏程序逻辑本身。 processSlave for循环已被修改为具有另一个条件pID != rank,该条件在发送TAG_QUIT消息时打破了导致跳过的逻辑。