簡體   English   中英

在 QList 上使用 QtConcurrent::map() function 會產生分段錯誤

[英]Using QtConcurrent::map() function on QList yields segmentation fault

我正在熟悉QtConcurrent庫。 我有一個 UI ( MainWindow ),我在其中運行我的函數來模擬真實世界的多線程示例。

我正在使用的QtConcurrent::map() function 需要一些:

  1. 迭代器或序列,就我而言,我使用的是QList
  2. 此外,它需要一個 MapFunctor(支持 lambdas*),但為此,我選擇堅持使用 static 方法進行測試。

我試過的

我嘗試使用兩個 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;
    }

    //...
}

Stacktrace(從調試器復制)

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 ??

作為記錄,還有另一個與此相關的問題,但大多數肯定沒有提供可用的解決方案。

為什么我會得到這個 SEGV,是什么導致了這個訪問沖突?

老實說,您的問題的某些部分對我來說並不清楚。 但是,請考慮以下幾點(盡管您可能已經考慮了部分或全部):

  1. 強烈建議函子為 static function。 從您的代碼看來,您可能沒有正確聲明 static function 。 請在 MainWindow.h 中添加以下內容:
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);;
}
  1. mapSumToQString是 static,因此您不能在其中使用MainWindow的非靜態成員。 因此, i也必須是 static。
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
  1. 修改 MainWindow.cpp 如下:
    // counter variable stored in MainWindow
    j = 0;

    QFuture<void> future;
    future = QtConcurrent::map(intPairList, mapSumToQString);
    future.waitForFinished();
  1. 我無法理解的一件事是您正在將 integer 轉換為具有隨機基數的字符串?!
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?

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM