Locking pattern to protect a critical List<> with many worker threads
-
Richard Andrew x64 wrote:
so that would lead to exceptions caused by changing the list out from under them.
That cannot happen. Per your original description the worker threads do not modify it. The management thread creates a new list. The worker threads never use that list until it is done and the management thread is done with it.
Richard Andrew x64 wrote:
seeing the new version of the list while other threads are still working with data from the old version of the list.
I think that requirement is going to end up requiring additional locking. Say you look up prices in a list. Then an execution flow looks like this
Worker1: Gets price X (v1) from list. Continues work
Management: rebuild list (simple lock)
Worker2: Starts (simple lock gone) and gets price X (v2) from list.
Worker1: Finishes work with v1
Worker2: Finishes work with v2jschell wrote:
That cannot happen.
Not even if the worker thread is in the middle of enumerating the list?
The difficult we do right away... ...the impossible takes slightly longer.
-
Threads take a **copy of the reference to the list**. Making a new list builds it brand new. There is no reason for threads to make a deep copy since the list, once made, never changes (only replaced as a whole). E: why are you making me re-explain your own idea back to you anyway? You know how this works, you suggested it.
The term 'shallow copy' means copying entities (objects) while using references to the contents rather than copying them also. It is not a term that applies to a reference/pointer by itself. My code does not copy any entities. It only uses a pointer via a temp variable. There are no entities in that for which a reference could be used. Sources for the definition of shallow copy IBM Documentation[^] Shallow copy - MDN Web Docs Glossary: Definitions of Web-related terms | MDN[^] https://www.techopedia.com/definition/25638/shallow-copy-c[^]
-
jschell wrote:
That cannot happen.
Not even if the worker thread is in the middle of enumerating the list?
The difficult we do right away... ...the impossible takes slightly longer.
Richard Andrew x64 wrote:
enumerating the list?
Correct. The Management thread creates a new list. Completely new. It does not modify nor touch the old list in any way. The worker threads, are using the old list. Because they copied the pointer, the old list is the only one that they can use. The old list is not modified. The pointer copy is the key to this behavior.
-
The term 'shallow copy' means copying entities (objects) while using references to the contents rather than copying them also. It is not a term that applies to a reference/pointer by itself. My code does not copy any entities. It only uses a pointer via a temp variable. There are no entities in that for which a reference could be used. Sources for the definition of shallow copy IBM Documentation[^] Shallow copy - MDN Web Docs Glossary: Definitions of Web-related terms | MDN[^] https://www.techopedia.com/definition/25638/shallow-copy-c[^]
-
Richard Andrew x64 wrote:
enumerating the list?
Correct. The Management thread creates a new list. Completely new. It does not modify nor touch the old list in any way. The worker threads, are using the old list. Because they copied the pointer, the old list is the only one that they can use. The old list is not modified. The pointer copy is the key to this behavior.
Yes, you're right, by George. So that implies that the reference assignment itself is atomic?
The difficult we do right away... ...the impossible takes slightly longer.
-
Yes, you're right, by George. So that implies that the reference assignment itself is atomic?
The difficult we do right away... ...the impossible takes slightly longer.
Richard Andrew x64 wrote:
So that implies that the reference assignment itself is atomic?
Yes that must be the case. For java and C# it is. Best I can tell in C++ the answer is sort of. Apparently it depends on the execution environment. But there is std:atomic. I wondered, when this thread started, if it was possible to have a language that supports threads where assignment was not atomic. (C++ the language does not support threads.)
-
Fine. You're not wrong, but you didn't have to be an ass about it. But that's nothing new for you.
-
My program contains a List<T> object that is extremely critical to the program's function. In normal use, it will be accessed by many ( >10 ) worker threads. I don't need to synchronize worker thread access, because the workers never write to the collection, it's read-only to the worker threads. However, I want to be able to make changes to the list in a single, central class. And I'd like to be able to temporarily shut off worker-thread access to the list while changes are being made by a thread in the central class. I'd like not to require the worker threads to acquire a mutex every time they need access due to performance reasons. So, is there a pattern by which I can make access to the List<T> very fast for the worker threads, but still be able to shut off worker access while the list is being updated by the central class?
The difficult we do right away... ...the impossible takes slightly longer.
In addition to what others have mentioned, could you not provide an EventHandler to notify of List Changing?
-
In addition to what others have mentioned, could you not provide an EventHandler to notify of List Changing?
You didn't complete the thought. What benefit would come from what you recommend?
The difficult we do right away... ...the impossible takes slightly longer.
-
You didn't complete the thought. What benefit would come from what you recommend?
The difficult we do right away... ...the impossible takes slightly longer.
You can use an EventHandler in conjunction with a EventWaitHandle to inform the worker thread that the list has changed and pass the new list so that the worker thread is always working with the new list rather than an old list.