Results 1 to 7 of 7

Thread: QVector COW thread-safety [Qt 4.8]

  1. #1
    Join Date
    Feb 2012
    Posts
    10
    Thanks
    2
    Thanked 1 Time in 1 Post
    Qt products
    Qt4 Qt/Embedded
    Platforms
    MacOS X Unix/X11 Windows

    Default QVector COW thread-safety [Qt 4.8]

    Is the copy-on-write behavior of QVector threadsafe?

    In particular, if I pass a copy-constructed QVector to a thread, the COW behavior indicates the data itself won't actually be copied until somebody does a write operation on one of instances. In a multi-threaded application is this transparent or does it require extra synchronization?

    For example (representative only):

    Qt Code:
    1. class Example : public QThread {
    2. public:
    3. Example (QVector<int> data) : data_(data) {
    4. }
    5. public void run () {
    6. while (true)
    7. doReadOnlyThingsWith(data_);
    8. }
    9. private:
    10. QVector<int> data_;
    11. }
    12.  
    13. void elsewhere () {
    14. QVector<int> data = ...;
    15. new Example(data)->start();
    16. new Example(data)->start();
    17. new Example(data)->start();
    18. new Example(data)->start();
    19. writeThingsToDataThatShouldntBeSeenByThreads(data);
    20. }
    To copy to clipboard, switch view to plain text mode 

    In the above example, multiple threads are using the data (read-only) while the main thread may go on to modify it, but the goal is that the modifications have no effect on the threads (that's why I passed it by value in the first place). Intuitively this should work, but is that really OK? Is the underlying copy-on-write threadsafe?

    The reason I ask is I'm trying to track down an infrequent seg fault and the debugger is not yielding helpful information. The only thing I noticed is that some of the threads are in QVector::realloc() when the program crashes, so I'm focusing on my usage of QVector.

    Thanks,
    J

  2. #2
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,360
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: QVector COW thread-safety [Qt 4.8]

    Accessing the shared pointer is thread-safe (which means that if two or more objects point to the same data and one of them needs a unique copy of the data so that it can be modified, it is guaranteed that no other thread will delete that pointer). Accessing data behind the pointer is not and you require dedicated synchronization.
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  3. #3
    Join Date
    Feb 2012
    Posts
    10
    Thanks
    2
    Thanked 1 Time in 1 Post
    Qt products
    Qt4 Qt/Embedded
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: QVector COW thread-safety [Qt 4.8]

    Thanks. So in other words, where this pattern is safe for primitives and non-COW objects:

    Qt Code:
    1. int valueForThread;
    2.  
    3. void threadFunction () {
    4. // do stuff with valueForThread
    5. }
    6.  
    7. void mainFunction () {
    8. int value = ...;
    9. valueForThread = value; // create a copy for thread
    10. startThread(&threadFunction);
    11. value = ...; // doesn't affect thread
    12. }
    To copy to clipboard, switch view to plain text mode 

    This would *not* be OK for a QVector:

    Qt Code:
    1. QVector<int> valueForThread;
    2.  
    3. void threadFunction () {
    4. // do stuff with valueForThread
    5. }
    6.  
    7. void mainFunction () {
    8. QVector<int> value = ...;
    9. valueForThread = value; // create a copy for thread
    10. startThread(&threadFunction);
    11. value = ...; // doesn't affect thread
    12. }
    To copy to clipboard, switch view to plain text mode 

    And therefore I need to review the documentation for a Qt object carefully before using it in this way to make sure no behind-the-scenes COW could be happening as a result and, if it is, synchronize accordingly. Correct?

    So in the above example I would need to protect 'valueForThread' with a mutex but *also* acquire the mutex when modifying 'value' in mainFunction()?

    Does that also mean an alternative is to somehow force a deep copy when doing 'valueForThread = value' so that I don't run into the problem at all and the copies become completely independent?

    Thanks.

  4. #4
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,360
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: QVector COW thread-safety [Qt 4.8]

    The pattern is safe in this context:

    Thread #1: vector2 = vector; vector2.append()
    Thread #2: vector = QVector<...>()

    Which means it is safe if you have two vectors pointing to the same data and you modify one of them. The pattern is not safe if two threads operate on the same object.
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  5. #5
    Join Date
    Nov 2012
    Posts
    21
    Thanked 2 Times in 1 Post
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: QVector COW thread-safety [Qt 4.8]

    This thread has confused me.

    I have always been under the impression that passing a copy of a QVector/QString etc to another thread would mean that they operate on the same data until one of them makes a change, and then it will do a deep copy in a threadsafe way and now they are operating on different data.

    This is all based on this article:
    http://marcmutz.wordpress.com/effective-qt/containers/
    (under the Copy-On-Write heading).
    which explicitly recommends using this mechanism to minimize time in mutex's.

  6. #6
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,360
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: QVector COW thread-safety [Qt 4.8]

    How would a deep-copy of a potentially very large vector data be made in a thread-safe way without using a mutex? The article explicitly show that an external mutex is required to protect the data structure while it is being copied (lines 26-30). And I'm not sure the code presented there is correct anyway.
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  7. #7
    Join Date
    Jan 2006
    Location
    Graz, Austria
    Posts
    8,416
    Thanks
    37
    Thanked 1,544 Times in 1,494 Posts
    Qt products
    Qt3 Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: QVector COW thread-safety [Qt 4.8]

    If you know that either thread is going to modify the data, why not create a deep copy in the first place?

    Qt Code:
    1. void mainFunction () {
    2. QVector<int> value = ...;
    3. valueForThread = value; // create a copy for thread
    4. valueForThread.detatch(); // create deep copy
    5. startThread(&threadFunction);
    6. value = ...; // doesn't affect thread
    7. }
    To copy to clipboard, switch view to plain text mode 

    Cheers,
    _

Similar Threads

  1. Thread safety with signals and slots
    By blooglet in forum Qt Programming
    Replies: 1
    Last Post: 15th March 2012, 16:03
  2. Thread safety
    By BalaQT in forum Qt Programming
    Replies: 6
    Last Post: 26th July 2011, 16:58
  3. QWidget and thread safety
    By spraff in forum Qt Programming
    Replies: 3
    Last Post: 22nd January 2009, 02:11
  4. QPointer and thread safety
    By Nb2Qt in forum Qt Programming
    Replies: 1
    Last Post: 22nd August 2008, 10:22
  5. QFile and thread-safety
    By Raistlin in forum Qt Programming
    Replies: 2
    Last Post: 31st January 2008, 16:42

Tags for this Thread

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.