簡體   English   中英

為什么單鏈表的Next()操作應由關鍵部分保護?

[英]Why should Next() operation of a singly linked list be protected with a critical section?

我正在閱讀Win32中的《 多線程應用程序 》一書

該書說, return node->next將被編譯成單獨的機器指令,這些指令不會作為原子操作執行,因此Next()也應由關鍵部分保護。

我的問題是,它會被翻譯成什么指令以引起比賽狀況?

typedef struct _Node
{
    struct Node *next;
    int data;
} Node;

typedef struct _List
{
    Node *head;
    CRITICAL SECTION critical_sec;
} List;

List *CreateList()
{
    List *pList = malloc(sizeof(List));
    pList->head = NULL;
    InitializeCriticalSection(&pList->critical_sec);
    return pList;
}

void DeleteList(List *pList)
{
    DeleteCriticalSection(&pList->critical_sec);
    free(pList);
}

void AddHead(List *pList, Node *node)
{
    EnterCriticalSection(&pList->critical_sec);
    node->next = pList->head;
    pList->head = node;
    LeaveCriticalSection(&pList->critical_sec);
}

void Insert(List *pList, Node *afterNode, Node *newNode)
{
    EnterCriticalSection(&pList->critical_sec);
    if (afterNode == NULL)
    {
        AddHead(pList, newNode);
    }
    else
    {
        newNode->next = afterNode->next;
        afterNode->next = newNode;
    }
    LeaveCriticalSection(&pList->critical_sec);
}

Node *Next(List *pList, Node *node)
{
    Node* next;
    EnterCriticalSection(&pList->critical_sec);
    next = node->next;
    LeaveCriticalSection(&pList->critical_sec);
    return next;
}

編輯:

好的,盡管在這種特殊情況下它不會破壞單個鏈表而不保護Next()操作,但是共享結構應該整體上受到保護,或者一無所獲。

return node->next執行兩項操作; 它首先將node指向的struct加載到內存中,然后查看node+offsetof(next)以查找next指針,將其加載到寄存器中,然后返回到調用程序。 同時, node的內容可能會被另一個執行線程操縱。

  1. 是的,您絕對需要在多線程應用程序中使用鎖來保護“下一個”。

...但是...

  1. “作家”(如添加或刪除節點) 必須互斥。 關鍵部分是一個不錯的選擇。

  2. “讀者”(例如“下一個”)可以彼此並發運行。

建議:

如果可以使用Windows Vista或更高版本,請考慮使用SRW鎖:

雖然我認為sarnold的答案是正確的,但我只是想指出,CreateList中malloc()調用中的sizeof()調用似乎有一個錯誤。 我相信它應該是:

List *pList = malloc(sizeof(List));

按照這種方式,您將創建足夠的內存來保存指向 List而不是List結構的指針 (您可能還希望將返回類型強制轉換為(List *)並將其與NULL比較,然后再使用。)

暫無
暫無

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

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