【问题标题】:Concurrency issue (Deadlock?)并发问题(死锁?)
【发布时间】:2019-10-18 05:15:26
【问题描述】:

我有一台服务器和多个客户端。服务器通过它的 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);线。预期结果是多次成功读取。

【问题讨论】:

  • 如果你能在遗嘱上产生死锁,你可以使用调试器看看是什么死锁...
  • WaitForSingleObject(hMutexServer, WAIT_ABANDONED); 那是什么?
  • @MichaelChourdakis 这是对先前死锁的修复,因为第一个客户端线程正在锁定服务器互斥锁,而最后一个客户端读取线程没有解锁它的权限。所以我的修补程序是等待废弃的服务器互斥体
  • WAIT_ABANDONED 是一个返回值,而不是应该传递给 WaitForSingleObject() 的参数。你是说if (WaitForSingleObject(hMutexServer,INFINITE) == WAIT_ABANDONED) 吗?
  • 锁的一个常见规则是锁只锁定一个特定数据,而不是其他任何东西,这意味着锁应该很容易与其受保护的数据相关联,并且应该被锁定只有在 i> 访问这些数据

标签: c multithreading winapi synchronization


【解决方案1】:

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

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

感谢 cmets Michael Chourdakis 和 OznOg。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-28
    • 2012-04-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多