Reputation: 1621
I figured it would be a lot easier if I drew a picture of my problem. Here it is:
Everything that is black in the diagram is part of the old design. Everything that is blue is part of the new design. Basically, I need to add a new thread (Worker Thread C) that will handle most of the work that Worker Thread B used to do. Worker Thread A is listening for real time updates from an external application. When he receives an update, he posts a message to Worker Thread B. Worker Thread B will set its copy of the new data (he still needs it in the new design) and then notify the GUI Thread as well as Worker Thread C that new data has arrived.
The user will send a request from the GUI to the new thread (Worker Thread C). Worker Thread C will process the request using the last received copy of the data that originally came from Worker Thread A. So my question is: Will Worker Thread C always be using the latest copy of the data when processing a request with this new design? What if Worker Thread B is too slow to update and then the user submits a request from the GUI? Thanks!
Upvotes: 0
Views: 168
Reputation: 17444
If I'm not mistaken, worker A is conceptually different than workers B and C, right? It rather looks like B and C handle user requests in the background in order to not block the UI. So, there could be a whole list of these background workers that perform UI operations or even none, while there will always be a worker A that pulls/receives updates.
Now, what I would do is that the worker A sends new data to the UI. The UI then uses this data in the next request. When it starts one of the workers like B or C, it just passes the data along with the other info that tells the thread what to do.
Note that you need to take care that you don't modify the data in different threads. The easiest way is to always copy the data when passing it between different parts, but that is often too expensive. Another easy way is to make the data constant. In worker A, you use a unique_ptr<Data>
to accumulate the update and then send that data as a shared_ptr<Data const>
to the UI thread. From that point on, this data is immutable (the compiler makes sure that you don't change it by accident) so it can be shared between threads without any further lock.
When creating a worker for a background operation, you pass in the shared_ptr<Data const>
. If it needs to modify that data, it would first have to copy it, but usually that isn't something that can't be avoided.
Notes:
Upvotes: 1