Stream deletion of a linked node list using a fine-grained approach

Why is the following snippet for deleting a node in a linked list not thread safe?

Edit: note that each node has its own

// ... lock acquisition here
// ... assumption found to be valid here
prev->next = p->next;
p->next = NULL;
p->deleted = 1;
+3
source share
3 answers

This is thread safe if you assume that the scope of your lock (which means it locks, has nothing to do with the official term "scope" used in C) is large enough.

If it only blocks the current node p, then you cannot rely on other threads not entering and playing with prev( heador tail, for that matter) and, therefore, cut you out.

, , -.

, ( ) .

, , p, . next null, deleted 1 , . . , , , , .


, , ( node):

"", , , - .

"" , head tail. , node node, head . node -node , head tail node.

"" .

(, head tail) .

, - .

, "" , , .

, . , , head node, head.

, node, , . , , , .


.

+5

, , 'prev' node -deletion. , , :

Head ==> A ==> B ==> C ==> D ==> Tail
               ^     ^
               |     |
        Thread 1     Thread 2

, Thread 1 node B. , Thread 2 node C . , , :

Thread 1                Thread 2
----------------------  ----------------------
Lock B                  Lock C
A->next = C or D; <=??  B->next = D;    <== B could be dead already
B->next = NULL;         C->next = NULL;
B->deleted = 1;         C->deleted = 1;
Unlock B                Unlock C

. Thread 2 Thread 1, . Thread 1 second line "A- > next = D", Thread 2 B- > D. , Thread 1 Thread 2, A- > next node C, node B , node D .

, node, , 'prev' . :

Thread 1                Thread 2
----------------------  ----------------------
Lock B                  Lock C
Lock A                  waiting for B
A->next = C;            waiting for B
Unlock A                waiting for B
B->next = NULL;         waiting for B
B->deleted = 1;         waiting for B
Unlock B                Lock B         <= locking dead node
                        B->next = D;   <= assigning to dead node
                        Unlock B
                        C->next = NULL;
                        C->deleted = 1;
                        Unlock C

, - . A- > node C, node B , D . , , , .

, , 'prev' node .

Thread 1                Thread 2
----------------------  ----------------------
Lock A                  Lock B
waiting for B           Lock C
waiting for B           B->next = D;
Lock B                  Unlock B  
A->next = D;            C->next = NULL;
Unlock A                C->deleted = 1;
B->next = NULL;         Unlock C
B->deleted = 1;         
Unlock B                

A- > D, B C .

+7

You can take a look at this presentation . From slide No. 39, he demonstrates how fine-grained blocking of linked lists should be implemented in a clear and imaginative way (slide notes also add some explanation). The presentation is based on (or taken from ...) a book called The Art of Multiprocessing Programming .

+7
source

Source: https://habr.com/ru/post/1794065/


All Articles