c++ - 两个线程可以同时读取同一个QList吗?

标签 c++ qt qthread qlist

对线程处理很陌生,我有线程之间共享的这个 QList。他们都有自己的工作空间,GUI(模型/ View )不断访问这个列表。然后我得到这个指向 QDataList.size() 的崩溃。调试并没有真正帮助我,因为如果我单步执行代码并且当我尝试崩溃的 qList 时,我从来没有遇到过这个问题,没有可用的信息。

所以,我的问题是:是否可以同时获取 Qlists 大小和读取对象?列表中的对象是线程安全的,不能同时被不同的线程读/写。

获取“0xC0000005:读取位置 0xfeeefefa 的访问冲突。”这让我想到: qlist.h 中的 inline int size() const

我遍历了调用堆栈,发现了这个:

QtCored4.dll!QListData::size()  Line 98 + 0x11 bytes    C++
QtNetworkd4.dll!QList<enum QNetworkReplyImplPrivate::InternalNotifications>::size()  Line 137 + 0x10 bytes  C++
QtNetworkd4.dll!QNetworkReplyImplPrivate::resumeNotificationHandling()  Line 444 + 0xe bytes    C++
QtNetworkd4.dll!QNetworkReplyImplPrivate::finished()  Line 797  C++
QtNetworkd4.dll!QNetworkAccessBackend::finished()  Line 313 C++
QtNetworkd4.dll!QNetworkAccessHttpBackend::replyFinished()  Line 739    C++
QtNetworkd4.dll!QNetworkAccessHttpBackend::qt_static_metacall(QObject * _o, QMetaObject::Call _c, int _id, void * * _a)  Line 86 + 0x8 bytes    C++
QtCored4.dll!QMetaCallEvent::placeMetaCall(QObject * object)  Line 525 + 0x1d bytes C++
QtCored4.dll!QObject::event(QEvent * e)  Line 1195 + 0x14 bytes C++
QtGuid4.dll!QApplicationPrivate::notify_helper(QObject * receiver, QEvent * e)  Line 4550 + 0x11 bytes  C++
QtGuid4.dll!QApplication::notify(QObject * receiver, QEvent * e)  Line 3932 + 0x10 bytes    C++
QtCored4.dll!QCoreApplication::notifyInternal(QObject * receiver, QEvent * event)  Line 876 + 0x15 bytes    C++
QtCored4.dll!QCoreApplication::sendEvent(QObject * receiver, QEvent * event)  Line 231 + 0x39 bytes C++
QtCored4.dll!QCoreApplicationPrivate::sendPostedEvents(QObject * receiver, int event_type, QThreadData * data)  Line 1500 + 0xd bytes   C++
QtCored4.dll!qt_internal_proc(HWND__ * hwnd, unsigned int message, unsigned int wp, long lp)  Line 496 + 0x10 bytes C++

每个线程都有一个执行网络请求的网络管理器:

QThread ASSERT failure in QMutexLocker: "QMutex pointer is misaligned",

最佳答案

我意识到可以预先分配一个 QList 并让线程对该列表的不同区域进行操作,但在我看来,我认为这是一个不好的模式。

当我使用 Qt 时(我实际上使用 PyQt,因为我是一名 Python 程序员),我觉得最好使用提供给您的信号/槽机制并且从不在线程之间共享内存。每个线程都应该在创建时直接获得自己的数据,或者随着时间的推移通过等待的队列获得。当它完成它的工作或一大块工作时,它可以发出一个带有数据的信号。您将拥有一个连接到所有线程的处理程序,以监听准备就绪的数据。

这种模式的结果是你没有共享内存,你不必太担心锁,而只是等待工作人员发出数据准备就绪的信号,并且单个处理程序正在收集和更新主要模型。

话虽这么说,这里是另一个引用资料,有人将 QList 用作共享内存并在锁定它之前遇到崩溃:http://developer.qt.nokia.com/forums/viewthread/13049

我认为当人们(包括我自己)第一次开始使用线程时,直接的冲动就是像他们一直那样使用容器。但是一旦开始线程化,代码逻辑的复杂性以及错误的容量就会立即增加。共享内存的同步是一种方法,在访问之前使用互斥体锁定资源。但我认为值得一提的是另一种沟通方式。

Google 的 Go 语言是根据其核心原则之一构建的:“不要通过共享内存进行通信;通过通信共享内存”http://golang.org/doc/codewalk/sharemem/

Go 希望通过 channel 对象(类似于 Qt 中的信号/槽)通信内存来解决这个问题的核心。一个组件具有对内存的独占本地访问权限,然后通过 channel 将其传递给另一个组件。这保证你不会有竞争条件。无论如何,我只是认为我会添加这个额外的引用,因为我觉得它与线程编程问题非常相关。

关于c++ - 两个线程可以同时读取同一个QList吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9476045/

相关文章:

c++ - 使用 QNetworkAccessManager 在 QT 中的 HTTP POST 请求

python - 当 GUI 退出时终止 QThread

c++ - CARLA RGB相机传感器的输出格式是什么

c++ - OpenCL C++ 上下文属性语法

c++ - 2 周前使用相同命令编译的程序中对 glutInit 的 undefined reference

python - 如何更改 Qthread 内 Qtimer 的时间间隔?

c++ - 为什么我的 worker 在错误的线程中工作?

c++ - OpenCl 代码在一台机器上工作,但我在另一台机器上得到 CL_INVALID_KERNEL_ARGS

c++ - Q_OBJECT 抛出 'undefined reference to vtable' 错误

c++ - 在 Qt 类的 getter 中按值返回