簡體   English   中英

為什么釋放信號量,但WaitForSingleObject()仍然卡住?

[英]Why semaphore is released but WaitForSingleObject() still stuck?

更新:我發現它們釋放的信號不是監視器線程正在等待的信號! 我用cout<<ready ,發現線程釋放的信號量是00000394 ,這不是監視線程正在等待的信號量的句柄。 此問題的可能原因是什么? 謝謝!


我是Windows中多線程編程的新手。 今天,當我編寫在線游戲服務器時,我嘗試在Windows中使用信號燈。 它是基於IOCP編寫的,因此每個消息都在單獨的線程中處理。 一個游戲包含4位玩家。

我希望它做的是:收到消息時,一個新線程啟動並釋放ready 有一個監視線程正在等待4個ready ,然后釋放4個all_ready 每個線程等待一個all_ready並繼續。

代碼在這里:

CGameHost是4人游戲的管理器。

CGameHost::CGameHost(void)
{
    init_times=0;
    ready = CreateSemaphore(NULL, 0, 4, NULL);
    read = CreateSemaphore(NULL, 0, 4, NULL);
    all_ready = CreateSemaphore(NULL, 0, 4, NULL);
    all_read = CreateSemaphore(NULL, 0, 4, NULL);
    monitor_thread = (HANDLE)_beginthreadex(NULL, 0, Monitor, (LPVOID)this, NULL, 0);
}

unsigned __stdcall CGameHost::Monitor( LPVOID p ) // a static function
{
    CGameHost *nowp = (CGameHost *)p;
    while(true)
    {
        int i;
        for(i=1;i<=MAX_PLAYER;i++)
        {
            WaitForSingleObject(nowp->ready, INFINITE);//stuck here
            cout<<"Get Ready!"<<endl; // This is not outputed, which means it stucks in the last row.
        }

        for(i=1;i<=MAX_PLAYER;i++)
        {
            ReleaseSemaphore(nowp->all_ready, 1, NULL);
        }

        for(i=1; i<=MAX_PLAYER; i++)
        {
            WaitForSingleObject(nowp->read, INFINITE);
        }

        for(i=1; i<=MAX_PLAYER;i++)
        {
            ReleaseSemaphore(nowp->all_read, 1, NULL);
        }
    }
    return 0;
}

void CGameHost::ReleaseReady()
{
    ReleaseSemaphore(ready, 1, NULL);
}

void CGameHost::WaitAllReady()
{
    WaitForSingleObject(all_ready, INFINITE);
}

void CGameHost::ReleaseRead()
{
    ReleaseSemaphore(read, 1, NULL);
}

void CGameHost::WaitAllRead()
{
    WaitForSingleObject(all_read, INFINITE);
}

DataProcess::Game是傳入游戲消息的消息處理程序。

CMessage Dataprocess::Game( CMessage* recv_msg )
{
    CMessage ret;
    int now_roomnum = recv_msg->para1;
    int now_playernum = recv_msg->para2;
    if(true)
    {
        cout<<"Received Game Message: "<<endl;
        cout<<"type2 = "<<recv_msg->type2;
        cout<<" player_num = "<<now_playernum<<" msg= "<<recv_msg->msg<<endl;
    }

    if(recv_msg->type2 == MSG_GAME_OPERATION)
    {
        ret.type1 = MSG_GAME;
        ret.type2 = MSG_GAME_OPERATION;

        cout<<"Entered from "<<now_playernum<<endl;

        game_host[now_roomnum].SetMessage(now_playernum, recv_msg->msg);
        game_host[now_roomnum].ReleaseReady();

        cout<<"Released Ready from "<<now_playernum<<endl;//this is shown

        game_host[now_roomnum].WaitAllReady();//stuck here

        cout<<"AllReady from"<<now_playernum<<endl;//not shown

    }
    return ret;
}

對於像我這樣的Windows多線程程序員的初學者,您的答復將大有幫助! 謝謝!

如果我了解您的需求,那么您可能應該有這樣的東西。

處理hPlayersReady [4]; 處理hAllPlayed;

創建這5個事件,然后在您的監視線程上,執行以下操作...

while(true)
{
// Wait for all players to move
WaitForMultipleObjects(4, &hPlayersReady, true, INFINITE);
// Process move
...
// Advise players the move was processed...
SetEvent(hAllPlayed);
}

在播放器線程X上

while(true)
{
// Make my move
...
// Advise monitor I'm ready
SetEvent(hPlayersReady[X]);
// Wait for ready to do another move
WaitForSingleObject(hAllPlayed);
}

好吧,我自己解決了。 原因是我在創建線程后再次使用了CreateSemaphore ,使播放器線程作為監視線程訪問了不同的信號量...對不起,我很愚蠢,非常感謝您告訴我!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM