加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c – 两个线程可以同时从同一个QList读取吗?

发布时间:2020-12-16 10:31:01 所属栏目:百科 来源:网络整理
导读:相当新的线程,我有这个线程在它们之间共享的QList.它们都有自己可以处理的空间,GUI(模型/视图)不断访问此列表.然后我得到这个指向QDataList.size()的崩溃.调试并没有真正帮助我,因为我从未遇到过这个问题,如果我单步执行代码,当我正在尝试qList崩溃时,没有可
相当新的线程,我有这个线程在它们之间共享的QList.它们都有自己可以处理的空间,GUI(模型/视图)不断访问此列表.然后我得到这个指向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++

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

QThread ASSERT failure in QMutexLocker: “QMutex pointer is misaligned”,

解决方法

我意识到可以预先分配一个QList并让线程在该列表的不同区域上运行,但在我看来,我认为这是一个糟糕的模式.

当我使用Qt(我实际上使用PyQt,因为我是一名python程序员)时,我觉得最好利用提供给你的信号/插槽机制,永远不要在线程之间共享内存.应该在创建时直接为每个线程提供自己的数据,或者通过等待的队列随时间给出每个线程.当完成其工作或大量工作时,它可以发出包含数据的信号.您将拥有一个连接到所有线程的处理程序,以侦听准备好的数据.

这种模式的结果是你没有共享内存,你不必担心锁定,而只是等待工人发信号通知他们的数据准备就绪,而单个处理程序正在收集和更新主模型.

话虽这么说,这是另一个使用QList作为共享内存并遇到崩溃直到他们锁定它的人的参考:http://developer.qt.nokia.com/forums/viewthread/13049

我认为,当人们(包括我自己)开始使用线程时,立即的冲动就是以与以往一样的方式使用容器.但是一旦你开始线程,你立即已经增加了代码逻辑的复杂性以及错误的容量.共享内存的同步是一种接近它的方法,使用互斥锁在访问之前锁定资源.但我认为值得一提的是另一种沟通方式.

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

Go希望通过在Qt中类似信号/插槽的通道对象上传输内存来解决这个问题.一个组件具有对内存的独占本地访问权限,然后通过通道将其传递给另一个组件.这保证你不会有竞争条件.无论如何只是认为我会提到这个额外的参考,因为我觉得它与线程编程问题非常相关.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读