我正在熟悉QtConcurrent库。我有一个UI (MainWindow),在这里我运行我的函数来模拟一个真实的多线程示例。
我使用的QtConcurrent::map()函数需要一些:
我已经尝试过的
我尝试使用这两个map()函数(第一个未注释)
我试着搜索一个序列和一个MapFunctor,但是我只能在模板中找到它,这对我没有多大帮助,所以我不得不尝试用我的直觉来理解它。
代码:
在我MainWindow.cpp的某个地方
// counter variable stored in MainWindow
int i = 0;
// MapFunctor
void mapSumToQString(QPair<int, int> pair)
{
i++;
qDebug() << "Execute " << i << " = " << QString::number(pair.first, pair.second);;
}以及启动这一切的代码
// UI class decl
MainWindow::MainWindow(QWidget* parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
// Create list of integers to perform map function on (here I don't write back to the original sequence i.e. list)
QList<QPair<int, int>> intPairList = QList<QPair<int, int>>();
for (int i = 0; i < 1000; i++) {
int i1 = qrand();
int i2 = qrand();
intPairList.append(QPair<int, int>(i1, i2));
}
QFuture<void> future;
future = QtConcurrent::map(intPairList, mapSumToQString);
// future = QtConcurrent::map(intPairList.begin(), intPairList.end(), mapSumToQString);
}问题:
运行此代码片段将生成SEGV 这里
namespace QtConcurrent {
// map kernel, works with both parallel-for and parallel-while
template <typename Iterator, typename MapFunctor>
class MapKernel : public IterateKernel<Iterator, void>
{
MapFunctor map;
public:
typedef void ReturnType;
MapKernel(Iterator begin, Iterator end, MapFunctor _map)
: IterateKernel<Iterator, void>(begin, end), map(_map)
{ }
bool runIteration(Iterator it, int, void *) override
{
map(*it); <--------SEGV line
return false;
}
//...
}堆栈跟踪(从调试器复制)
1 QtConcurrent::MapKernel<QList<QPair<int, int>>::iterator, QtConcurrent::FunctionWrapper1<void, QPair<int, int>>>::runIteration qtconcurrentmapkernel.h 68 0x404ee8
2 QtConcurrent::MapKernel<QList<QPair<int, int>>::iterator, QtConcurrent::FunctionWrapper1<void, QPair<int, int>>>::runIterations qtconcurrentmapkernel.h 77 0x404f82
3 QtConcurrent::IterateKernel<QList<QPair<int, int>>::iterator, void>::forThreadFunction qtconcurrentiteratekernel.h 255 0x40466e
4 QtConcurrent::IterateKernel<QList<QPair<int, int>>::iterator, void>::threadFunction qtconcurrentiteratekernel.h 217 0x404486
5 QtConcurrent::ThreadEngineBase::run qtconcurrentthreadengine.cpp 302 0x6d881973
6 QThreadPoolThread::run qthreadpool.cpp 99 0x111b36a
7 QThreadPrivate::start(void *) *4 qthread_win.cpp 403 0x11163eb
8 KERNEL32!BaseThreadInitThunk 0x74d56359
9 ntdll!RtlGetAppContainerNamedObjectPath 0x77467c24
10 ntdll!RtlGetAppContainerNamedObjectPath 0x77467bf4
11 ??为了记录在案,还有另一个与此相关的https://stackoverflow.com/questions/52431737/qtconcurrentmap-segmentation-fault,但肯定没有提供可用的解决方案。
为什么我要得到这个SEGV,是什么导致了这个访问违规?
发布于 2020-06-01 07:24:09
老实说,你的一些问题对我来说还不清楚。然而,请考虑以下各点(尽管你可能已经考虑了其中的一部分或全部):
static void mapSumToQString(QPair<int, int> pair);并将实现修改如下:
// MapFunctor
void MainWindow::mapSumToQString(QPair<int, int> pair)
{
j++;
qDebug() << "Execute " << j << " = " << QString::number(pair.first, pair.second);;
}mapSumToQString是静态的,因此不能在其中使用MainWindow的非静态成员。因此,i也必须是静态的。static int j; //in MainWindow.h ---> I changed i to j to make it differ from your For loop variable
int MainWindow::j = 0;//in MainWindow.cpp ----> static variables have to be initialized // counter variable stored in MainWindow
j = 0;
QFuture<void> future;
future = QtConcurrent::map(intPairList, mapSumToQString);
future.waitForFinished();qDebug() << "Execute " << j << " = " << QString::number(pair.first, pair.second);
//Herein, pair.second is random, and hence QString::number's second input (base) is always a random number. Do you really want it?https://stackoverflow.com/questions/62124748
复制相似问题