QtConcurrent问题
一个单例,单例内实例化了一个源model和一个消息订阅管理器controller,controller接收到新消息就会更新源model。单例提供了接口createTable用来创建显示数据的页面(可以创建多个页面),这个页面类中有一个QSortFilterProxyModel的派生类用来展示数据并进行排序和筛选(多个页面的proxyModel指向一个源model)。考虑到数据量大的情况下排序和筛选会比较耗时,所以我用QtConcurrent来创建一个线程,线程结构如下:
QtConcurrent::run([=]() {
while (m_bThreadRunning)
{
QPair<int, QVariantMap> task;
task.first = NoTask;
if (!m_taskQueue.isEmpty())
{
QMoutexLocker locker(&m_mutex);
if (!m_taskQueue.isEmpty())
{
task = m_taskQueue.dequeue();
}
}
switch (task.first)
{
case SortTask:
{
int column = task.second.data("column").toInt();
Qt::SortOrder order = Qt::SortOrder(task.second.data("order").toInt());
// 排序
QSortFilterProxyModel::sort(column, order );
emit taskFinished();
}
break;
case FilterTask:
// 过滤
invalidateFilter();
emit taskFinished();
break;
default:
break;
}
}
});
我用类似的结构创建了三个不同名的单例类A,B,C,把它们打包到一个库中了,使用的时候,在一个项目的两个不同模块中都用到了这个展示数据的页面,所以同一个单例的createTable被调用了两次,我发现:
第一个初始化的模块中的三个页面数据的筛选和过滤是正常的,第二个模块中只有第一个调用的createTable创建的页面的筛选和过滤是正常的,但是其他两个都不能进行筛选和过滤。
通过断点调试后发现,那两个不能筛选和过滤的页面实际上已经把筛选/排序任务都加载到m_taskQueue队列中了,任务一直在这个队列中累加却没有被消费,但是对QtConcurrent这段代码打断点,发现m_taskQueue却始终为空,仿佛在QtConcurrent中又实例化了一个新的m_taskQueue。这个问题的奇怪之处就在于,A单例createTable在两个模块中创建的两个页面都是正常的,BC却只在第一个模块中正常,在第二个模块中就出问题了。
QtConcurrent::run([=]() {
while (m_bThreadRunning)
{
QPair<int, QVariantMap> task;
task.first = NoTask;
if (!m_taskQueue.isEmpty())
{
QMoutexLocker locker(&m_mutex);
if (!m_taskQueue.isEmpty())
{
task = m_taskQueue.dequeue();
}
}
switch (task.first)
{
case SortTask:
{
int column = task.second.data("column").toInt();
Qt::SortOrder order = Qt::SortOrder(task.second.data("order").toInt());
// 排序
QSortFilterProxyModel::sort(column, order );
emit taskFinished();
}
break;
case FilterTask:
// 过滤
invalidateFilter();
emit taskFinished();
break;
default:
break;
}
}
});
我用类似的结构创建了三个不同名的单例类A,B,C,把它们打包到一个库中了,使用的时候,在一个项目的两个不同模块中都用到了这个展示数据的页面,所以同一个单例的createTable被调用了两次,我发现:
第一个初始化的模块中的三个页面数据的筛选和过滤是正常的,第二个模块中只有第一个调用的createTable创建的页面的筛选和过滤是正常的,但是其他两个都不能进行筛选和过滤。
通过断点调试后发现,那两个不能筛选和过滤的页面实际上已经把筛选/排序任务都加载到m_taskQueue队列中了,任务一直在这个队列中累加却没有被消费,但是对QtConcurrent这段代码打断点,发现m_taskQueue却始终为空,仿佛在QtConcurrent中又实例化了一个新的m_taskQueue。这个问题的奇怪之处就在于,A单例createTable在两个模块中创建的两个页面都是正常的,BC却只在第一个模块中正常,在第二个模块中就出问题了。
...全文
相关推荐
qtconcurrent 多线程并发处理
在实际项目中,需要注意线程间的同步问题,避免竞态条件和死锁,确保程序的正确性和稳定性。
便捷的使用多线程并发类QtConcurrent解决Qt在槽函数中执行耗时操作导致界面卡住的问题
便捷的使用多线程并发类QtConcurrent解决Qt在槽函数中执行耗时操作导致界面卡住的问题 如果你在静态函数中不操作UI和成员函数的话现在函数已经可以正常使用了,若果使用UI和成员函数则需要声明静态指针,用静态指针去访问! 不用静态指针访问的问题 mainwindow.cpp:264:21: error: invalid use of member 'ui' in static member function ............
QtConcurrent.rar
为了确保线程安全,QtConcurrent使用了内部的锁和同步机制,避免了数据竞争的问题。然而,开发者仍然需要注意避免在多个线程中同时修改同一数据结构,这可能会引发未定义的行为。
Qt 线程池(QThreadPool )的使用
在编写多线程应用时,需要注意线程安全问题,特别是当多个线程访问同一数据时。Qt提供了信号和槽机制,使得线程间的通信变得简单且安全。
Qt QtConcurrent 多线程 demo
本篇将深入探讨QtConcurrent的相关知识点,并通过提供的"Qt QtConcurrent 多线程 demo"进行实例解析。首先,我们了解下多线程的概念。


