11/14/2013

多執行緒(multi-thread) - 避免發生死結(死鎖)(deadlock)的小技巧(二)

來發表一下thread經驗談...

據我使用thread多年的經驗發現,
要避免死結,除了我以前列出的重點之外,
最好的方式就是...

不要Lock多個物件後才處理邏輯

這個設計限制,將能杜絕死結的產生,
但寫起來會稍微麻煩點!


說明範例如下:

一般的Lock方式(多重lock互套,容易發生死結):
void PlayerAttackEnemy( char *player1_name, char *player2_name )
{
    PlayerInfo *player1_node = GetPlayer( player1_name );
    PlayerInfo *player2_node = GetPlayer( player2_name );

    player1_node->Lock();
    player2_node->Lock();

    player1_node->HP -= player2_node->Strength + player2_node->Equip;
    player2_node->AttackExp += 1;

    player2_node->Unlock();
    player1_node->Unlock();
}

改寫後(禁止多重lock互套,不會發生死結):
void PlayerAttackEnemyForThreadSafe( char *player1_name, char *player2_name )
{
    PlayerInfo *player1_node = GetPlayer( player1_name );
    PlayerInfo *player2_node = GetPlayer( player2_name );

    player2_node->Lock();

    DWORD attack = player2_node->Strength + player2_node->Equip;
    player2_node->AttackExp += 1;

    player2_node->Unock();

    //---------------------

    player1_node->Lock();

    player1_node->HP -= attack;

    player1_node->Unlock();
}

看出其中的差異了嗎?這非常重要喔!

範例寫法可以繼續衍生很多種,但觀念則是不變的。
請記住:不要Lock多個物件後才處理邏輯

謝謝觀賞~


延伸閱讀:
3D線上遊戲製作軟體 - 多執行緒(multi-thread) - 避免發生死結(死鎖)(deadlock)的小技巧!(一)

沒有留言: