Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. QtConcurrent::map() vs. QtConcurrent::run() for member function
Forum Updated to NodeBB v4.3 + New Features

QtConcurrent::map() vs. QtConcurrent::run() for member function

Scheduled Pinned Locked Moved General and Desktop
6 Posts 3 Posters 2.9k Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • E Offline
    E Offline
    edtasker
    wrote on 28 Apr 2014, 06:20 last edited by
    #1

    I have a QWidget class called "createCPInput" with a public member function "void generateAxtCPseq()" and a slot "void on_generateCPInputButton_clicked()". the function generateAxtCPseq() can take a long time to run so I run it within "on_generateCPInputButton_clicked()" using QtConcurrent::run() so that it runs in a separate thread.

    I want to be able to get progress signals and be able to cancel the thread, these features aren't compatible for QtConcurrent::run() but are compatible for QtConcurrent::map(). I haven't been able to figure out a way to run generateAxtCPseq() using QtConcurrent::map().

    If anyone has some suggestions that would be great.

    Here is the relevant code I have at the moment which runs fine but doesn't allow me the functionality I require:
    createcpinput.h

    @
    public:
    void generateAxtCPSeq();

    private slots:
    void on_generateCPInputButton_clicked();
    @

    createcpinput.cpp
    @
    void createCPInput::on_generateCPInputButton_clicked(){
    typedef QFutureWatcher<void> voidWatcher;
    voidWatcher *axtWatcher = new voidWatcher(this);
    axtWatcher->setFuture(QtConcurrent::run(this,&createCPInput::generateAxtCPSeq));
    }

    void createCPInput::generateAxtCPSeq(){
    //Computationally expensive task
    }
    @

    1 Reply Last reply
    0
    • M Offline
      M Offline
      MuldeR
      wrote on 28 Apr 2014, 12:00 last edited by
      #2

      QtConcurrent::map() has the following interface:
      @map(Sequence &sequence, MapFunction function)@

      Hence you need a Sequence, containing the items to be processed, plus a MapFunction, which will be called once for each item to be processed.

      Also your MapFunction function must take a reference to an item as input and it must process that item. It can not be an arbitrary function!

      BTW: The reason why QtConcurrent::map() can be "cancelled" is because it will call your function once for each item. So it can simply stop calling your function before all items have been processed, when "cancellation" is requested. It still cannot "abort" a single call of your function!

      __

      See also:
      http://qt-project.org/doc/qt-4.8/qtconcurrent-map-main-cpp.html

      My OpenSource software at: http://muldersoft.com/

      Qt v4.8.6 MSVC 2013, static/shared: http://goo.gl/BXqhrS

      Go visit the coop: http://youtu.be/Jay...

      1 Reply Last reply
      0
      • E Offline
        E Offline
        edtasker
        wrote on 29 Apr 2014, 00:29 last edited by
        #3

        Thanks MuldeR for the reply.

        So, It seems like I'm going down the wrong path for what I want to do.

        The reason generateAxtCPSeq() takes a long time is because it reads in large data files and writes out a large amount of data. Initially I had this running in the same thread when on_generateCPInputButton_clicked() was called. This was causing my GUI to be non-responsive. After some searching I found this: http://doc.qt.digia.com/qq/qq27-responsive-guis.html. But because I call the function generateAxtCPSeq() only once there isn't a way to cancel it or get progress signals from it.

        Is there a way to perform the reading and writing in another thread but be able to cancel and get progress reports from it? it doesn't seem obvious because the reading and writing needs to happen sequentially (reading in line by line).

        1 Reply Last reply
        0
        • H Online
          H Online
          hskoglund
          wrote on 29 Apr 2014, 00:56 last edited by
          #4

          Hi, perhaps instead try a "QThread class":https://qt-project.org/doc/qt-5/qthread.html . And you can use signal/slots for cancels and process reports.

          1 Reply Last reply
          0
          • M Offline
            M Offline
            MuldeR
            wrote on 29 Apr 2014, 10:39 last edited by
            #5

            You cannot abort generateAxtCPSeq(), unless that function offers a way to do so! Of course you could run the function is a separate thread, e.g. by using QThread. Then you could simply kill the thread in order to "abort" the function. But this is inherently unsafe! You would kill the function at an arbitary position, resulting in undefined behavior. You can get resource leaks and other evils. Don't do this, if it can be avoided!

            Better change your function like this:
            @bool generateAxtCPSeq(volatile bool *abortFlag)
            {
            while((!completed) && (!(*abortFlag)))
            {
            doNextStep();
            }
            return complete;
            }@

            Then you could pass a pointer to a global "abortFlag" variable, which you set to false initially and which you can set to true, from the "main" thread, in order to abort the function call. This of course assumes your function can be broken down into a number of "short" steps.

            __

            It could look like this:

            @class MyThread : public QThread
            {
            public:
            MyThread(void)
            {
            m_success = m_abortFlag = false;
            }

            void abortFunction(void)
            {
                m_abortFlag = true;
            }
            

            protected:
            virtual void run(void)
            {
            m_success = generateAxtCPSeq(&m_abortFlag);
            }

            volatile bool m_abortFlag;
            volatile bool m_success;
            

            };@
            @void MyDialog::startButtonPressed(void)
            {
            m_thread->start();
            }

            void MyDialog::abortButtonPresed(void)
            {
            m_thread->abortFunction();
            }@

            My OpenSource software at: http://muldersoft.com/

            Qt v4.8.6 MSVC 2013, static/shared: http://goo.gl/BXqhrS

            Go visit the coop: http://youtu.be/Jay...

            1 Reply Last reply
            0
            • E Offline
              E Offline
              edtasker
              wrote on 30 Apr 2014, 04:09 last edited by
              #6

              Thanks MuldeR that's really helpful :D

              1 Reply Last reply
              0

              1/6

              28 Apr 2014, 06:20

              • Login

              • Login or register to search.
              1 out of 6
              • First post
                1/6
                Last post
              0
              • Categories
              • Recent
              • Tags
              • Popular
              • Users
              • Groups
              • Search
              • Get Qt Extensions
              • Unsolved