Ok, recently I’ve been thinking about thread safety a lot and I was wondering why linked lists or deques are not thread safe.
Let’s assume we have a simple linked list class like this:
class myLinkedList {
private:
myLinkedList* next;
int m_value;
public:
myLinkedList() { next = NULL; m_value = 0; }
void setValue(int value) { m_value = value; }
int getValue() { return m_value; }
void addNext(int value) { next = new myLinkedList; next->setValue(value); }
myLinkedList* getNext() { return next; }
};
Now I just want to add new elements at the end and delete elements (read them first and then delete them) at the beginning. I basically just get the address of the first next, delete the first element and remember the next as my new first element. For adding new elements I only remember the last element and when I add a new element I just set a new next and remember my new next as the last element.
Where is the problem with threads in this scenario? Writers and readers shouldn’t have any problems with this since they never interact with each other. It’s not like using arrays or vectors (there I very well get why it causes problems).
The comments to your question are correct, your implementation will not work. However, to answer the actual question, here’s a race condition in your code:
Imagine that thread A executes:
Now thread A gets preempted, and thread B also executes the same instruction. That means that
nextnow doesn’t point to wherever thread A wants it to point to, but instead it points to wherever thread B set it. Thread B continues the execution with:Soon after that (or even at the same time), thread A also executes the above.
Can you see the problem? Thread A calls
next->setValue()on B’snextand A’snextis lost.