0
votes

In my Qt C++ application, I have two main threads: the GUI thread and the render thread. The GUI thread manages a list of DataObject structs that can be created and edited, while the render thread draws the objects (the render thread is unable to modify the data objects). I need a way to share the data objects between the two threads (the render thread can render thousands of objects per frame and the objects usually store hundreds of pairs of floating point numbers). Currently, my design strategy consists in storing shared_ptr of data objects and pass a list of shared pointers from the GUI thread to the render thread. I'm using mutexes and locks to prevent data races when the GUI thread is modifying a data object and the render thread is also trying to read the same data object.

On the other hand, looking at the Qt source code I see that a lot of use of the Copy-on-write technique which essentially involves shallow copies of the data objects when the access is read only and deep copies for write access. Qt also provide convenient classes like QSharedData classes to implement your own implicitly shared objects.

So in my case, I was contemplating the use of copy-on-write so that I could implement my DataObject using this technique. Instead of passing shared pointers to the render thread, I could directly pass DataObject instances (of course internall the data is still stored using a pointer) and in case the GUI thread tries to modify a data object, it would just copy the data and the two threads would continue as if they own the data object (the render thread would eventually discard its copy). Now, it seems to me that copy-on-write is quite unpopular inside the C++ world (outside of Qt) and I haven't found many examples of its use in other codebases. What would be the disadvantages of using copy-on-write in my scenario? Are there any pitfalls that I should be aware of?

When does your "reading" thread should have its "modified" data updated?Jarod42
Essentially each frame my GUI threads sends a list of data objects to be rendered. So the render thread would receive the modified data on the beginning of the next frame.reckless