Can two threads read from the same QList at the same time?

后端 未结 2 1510
暗喜
暗喜 2021-01-14 18:07

Pretty new to threading and I have this QList that the threads share between them. They all have their own space that they can work on, and the GUI (the model/view) access t

相关标签:
2条回答
  • 2021-01-14 18:23

    No, they can't Err, maybe/probably. The documentation says that all QList functions are only reentrant, and not thread-safe. Now, normally reading from a shared structure should be thread-safe, but in this case Qt has explicit documentation and there is no exception made for reading. You therefore have to assume that it is not allowed and may result in errors.

    Note that a std::list does not suffer from this problem and allows reading from multiple threads (writing must of course still be exclusive).

    Note that Qt threading overall has a lot of special cases, it is was prompted me to write "requirements for a threaded API", many of which Qt fails. Part of this is history, and part of this is dealing with a variety of hardware, but in general Qt threading must be treated specially.


    Since the docs are not consistent (see comment) I did a quick review of the QList source code. Simple functions like "begin", "size" and "first" do appear to be read-only. They do not modify the data structure. Thus if they are causing a crash it is because some other thread is modifying the list at the same time.

    0 讨论(0)
  • 2021-01-14 18:28

    I realize that its possible to pre-allocate a QList and let threads operate on different areas of that list, but in my opinion I think its a bad pattern to follow.

    When I work with Qt (I actually work with PyQt since I'm a python programmer), I feel its best to make use of the signal/slot mechanism that is provided to you and never share memory between threads. Each thread should be given its own data either directly at creation, or over time through a queue that is waits on. When it is done with its work or a chunk of work it can emit a signal with the data. You would have a single handler that connects to all of your threads to listen for data to be ready.

    The result of this pattern is that you aren't sharing memory and you don't have to worry so much about locks, but rather just waiting for workers to signal their data is ready, and a single handler is collecting and updating the main model.

    That being said, here is another reference of someone using a QList as shared memory and experiencing crashes until they locked it: http://developer.qt.nokia.com/forums/viewthread/13049

    I think when people (myself included) first start working with thread the immediate impulse is to just use containers the same way they always have. But once you start threading you immediately already increase both the complication of the codes logic as well as the capacity for bugs. Synchronization of shared memory is one way to approach it, using mutexes to lock resources before access. But I think its worth mentioning another way which is communicating.

    Googles Go language was built with one of its core principles being: "Dont communicate by sharing memory; share memory by communicating" http://golang.org/doc/codewalk/sharemem/

    Go wanted to address this issue at its core by communicating memory over channel objects, which resemble signal/slot in Qt. One component has exclusive local access to memory and then pass it along to another component over a channel. This gurantees you wont have race conditions. Anyways just thought I would tack on this extra reference because I feel its very relevant to thread programming issues.

    0 讨论(0)
提交回复
热议问题