首页 > 解决方案 > 并发问题(死锁?)

问题描述

我有一台服务器和多个客户端。服务器通过它的 main 函数使用第一个函数,客户端通过线程调用第二个函数(一个客户端使用一个线程在无限循环中读取)。

这是一个学校作业,最终目的是通过共享内存传递gameData结构,重新创建打砖块游戏

BOOL EmitBroadcast(JOGO * structure) {//called by the server
    WaitForSingleObject(hMutexServer, WAIT_ABANDONED);
    structure->numPlayersAtivosAux = structure->numPlayersAtivos;

    memcpy(pBufGameData, structure, sizeof(JOGO));

    ReleaseMutex(hMutexServer);
    SetEvent(hServerHasWritten);

    return TRUE;
}

JOGO ReceiveBroadcast(JOGO * structure) {//used by the client's thread in loop
    //R/W de Michel Raynal 
    WaitForSingleObject(hServerHasWritten, INFINITE);
    WaitForSingleObject(hMutexCliente, INFINITE);//lock r

    structure= &(*pBufGameData);

    if (structure->numPlayersAtivosAux == structure->numPlayersAtivos) {
        WaitForSingleObject(hMutexServer, INFINITE);//lock g
    }

    structure= pBufGameData;

    (structure->numPlayersAtivosAux)--;
    memcpy(pBufGameData, structure, sizeof(JOGO));

    if (structure->numPlayersAtivosAux == 0) {
        ReleaseMutex(hMutexServer);//unlock g
        ResetEvent(hServerHasWritten);
    }

    ReleaseMutex(hMutexCliente);//unlock r

    return * structure;
}

void receiveLoop(LPVOID lParam) {//client thread loop function
    JOGO * gameInfoIn = (JOGO *)lParam;

    do {
        *gameInfoIn = ReceiveBroadcast(gameInfoIn);
        _tprintf(TEXT("\n%d"), gameInfoIn->vidas);

        Sleep(300);//testing purposes
    } while (closeThreadReceiveLoop || gameInfoIn->vidas != 0);
}

当我打开多个客户端和服务器时,在每个客户端成功读取 1 次后,服务器正确发送并且一个客户端锁定在 WaitForSingleObject(hMutexServer, INFINITE); 线。预期结果是多次成功读取。

标签: cmultithreadingwinapisynchronization

解决方案


好的,正如 Michael Chourdakis 在评论中指出的那样,我在 WaitForSingleObject 函数中有一个错误的参数。我通过向第一个阻止 serverMutex 的客户端添加一个事件来解决这个问题。

这使得第一个客户端线程等待剩余的客户端线程完成。最后一个客户端线程触发事件,第一个客户端能够终止并释放服务器互斥锁。

感谢 Michael Chourdakis 和 OznOg 的评论。


推荐阅读