about QtConcurrent::run,why some thread not run?



  • this is my code:

    MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    {
    for(int i = 0; i < 10; i++)
    {
    QtConcurrent::run(this, &MainWindow::threadFunc, i);
    qDebug() << i;
    Sleep(1);
    }
    }

    void MainWindow::threadFunc(int ix)
    {
    qDebug() << ix << QThread::currentThreadId();
    while(1)
    {
    Sleep(1);
    }
    }

    this is debug info:

    Debugging starts
    0 0x3648
    0
    1
    1 0x2df4
    2
    2 0x378
    3
    3 0x369c
    4
    4 0x1254
    5
    5 0x290c
    6
    6 0x243c
    7
    7 0x2008
    8
    9
    Debugging has finished

    why 8 and 9 thread not run?



  • Maybe my understanding of QtConcurrent is wrong, but I thought that it basically set up one thread per available core and then assigned tasks as the threads became available. In which case, the reason that your 9th and 10th tasks don't run is because there are only eight running threads, and the function running in those threads never finishes. That is, the thread is never available to a later process because your first process is an infinite loop. What are you actually trying to accomplish with QtConcurrent? It may be that you need a lower-level functionality.


  • Moderators

    @a-normal-worker @Chris-Hennes is right. You should read the documentation (http://doc.qt.io/qt-5/qtconcurrent.html#run):
    "Runs function in a separate thread. The thread is taken from the global QThreadPool. Note that function may not run immediately; function will only be run once a thread becomes available."
    QConcurrent::Run uses a thread pool. If all threads from this pool are busy it will not start any new jobs. That is you problem: you start 8 jobs which never finish and the pool seems to have a size of 8, so your jobs 9 and 10 are not started as there are no free threads in the thread pool.
    It does not make sense to start too many threads as a CPU can only handle a certain amount of threads at the same time. There is a rule of thumb: number of concurrent threads should be = number of CPU cores + 1. In case your CPU has hyper threading you should use 2*(number of cores) + 1.



  • This post is deleted!


  • @Chris-Hennes @jsulm thanks very much.
    My goal is to open 10 threads, read the larger files of the 10, they must all be read to ensure the normal operation of the program.
    There are other better ways to achieve it?



  • Here's a new test:
    while(1)
    {
    Sleep(1);
    }
    change into:
    while(1)
    {
    static int v = 0;
    if(v++ > 10000)
    break;
    Sleep(1);
    }

    this debug info:
    Debugging starts
    0 0x2dfc
    0
    1
    1 0xb10
    2
    2 0x7a4
    3
    3 0x1aec
    4
    4 0x214c
    5
    5 0x3294
    6
    6 0xe3c
    7
    7 0x32b8
    8
    9
    9 0x3294
    8 0xb10
    Debugging has finished

    They are like signals and slots using Qt:: QueuedConnection,But this is not what I want, I need these 10 threads to run at the same time


  • Moderators

    @a-normal-worker said in about QtConcurrent::run,why some thread not run?:

    @Chris-Hennes @jsulm thanks very much.
    My goal is to open 10 threads, read the larger files of the 10, they must all be read to ensure the normal operation of the program.
    There are other better ways to achieve it?

    Since you want to run the same function in multiple threads, I suggest using QtConcurrent::map() instead of QtConcurrent::run(): http://doc.qt.io/qt-5/qtconcurrentmap.html

    This way, you can easily wait for all iterations to finish before your application quits.



  • @a-normal-worker

    I'm still not sure what you try to accomplish with the 10 threads, but if you need 10 different threads to run simultaneously Qt::Concurrent is not the way to go.

    Take a look at this Example of general useage of QThreads. You can run an indefenet amount of Threads parallel if you follow that example.

    BUT keep in mind, when you exeed your threadpool, all your threads will no longer run simultaneously but will be processed alternately by your OS


  • Moderators

    @a-normal-worker Again: a CPU can only execute a certain amount of threads at the same time (8 in your case, that's why 8 and 9 are executed later). You should not expect that it can execute 10 at the same time - it just can't.



  • @JKSH @jsulm @J-Hilk thanks.

    My goal is to simulate concurrency, from 10 files to obtain data to control the underlying equipment. I have not used QtConcurrent before. Now I will be QtConcurrent :: run (this, & MainWindow :: threadFunc, i) to std :: thread (& MainWindow :: threadFunc, this, i) after you can immediately open 10 threads, although they may not really Meaning the same time running. But my engineering environment can not use C ++ 11, so I need to find a function similar to std :: thread in QT



  • @a-normal-worker

    Let me expand the example I linked a bit and tell me if its close to what you want.

    class Worker : public QObject {
        Q_OBJECT
    public:
        Worker(QString path);
        ~Worker();
    public slots:
        void process();
    signals:
        void finished();
        void lineRead(QString line);
        void error(QString err);
    private:
        QFile fileToRead;
    };
    
    Worker::Worker(QString path) { // Constructor
        fileToRead = QFile(path);
    }
     
    Worker::~Worker() { // Destructor
        // free resources
    }
     
    void Worker::process() { // Process. Start processing data.
        // allocate resources using new here
            if(fileToRead.open(QIODevice::ReadOnly)){
               QTextStream tStream(&fileToRead);
    
               while(!tStream.atEnd()){
                   emit lineRead (tStream.readLine());
               }
            }else
                emit error("File could not be opened!");
        emit finished();
    }
    
    QList<QString> files{"file1.txt","file2.txt", ..... ,"file10.txt"}
    
    for(int i = 0; i < files.size(); i++){
       QThread* thread = new QThread;
       Worker* worker = new Worker(files[i]);
       worker->moveToThread(thread);
       connect(worker, SIGNAL (error(QString)), this, SLOT (errorString(QString)));
       connect(worker, SIGNAL (lineRead(QString)), this, SLOT (newFileString(QString)));
       connect(thread, SIGNAL (started()), worker, SLOT (process()));
       connect(worker, SIGNAL (finished()), thread, SLOT (quit()));
       connect(worker, SIGNAL (finished()), worker, SLOT (deleteLater()));
       connect(thread, SIGNAL (finished()), thread, SLOT (deleteLater()));
      thread->start();
    }
    

    If Ididn't miss anything, than nothing in this example relies on c++ 11



  • @J-Hilk They are in the same thread.
    Worker::Worker(int ix)
    {
    qDebug() << ix << QThread::currentThreadId();
    }
    0 0x2028
    1 0x2028
    2 0x2028
    3 0x2028
    4 0x2028
    5 0x2028
    6 0x2028
    7 0x2028
    8 0x2028
    9 0x2028

    The above is my understanding of the error, the constructor is in the main thread, only the worker class function is in other threads.Your method is right,thanks.



  • @a-normal-worker
    let my quote @kshegunov from this topic why the thread Id is the same for the objects.

    Of course they have. The thread objects all live in the main thread in your code and that's absolutely normal. The QThread class manages a thread, it is not a thread itself. The only thing that's executed in a new thread context is QThread::run (which you don't touch when doing the worker object anyway). The slots of your worker object are executed in the new thread (granted you don't use Qt::DirectConnection when connecting).



  • @J-Hilk I just got it wrong. Now I know. Thank you very much.



  • Thanks to everyone, thanks to Google translate,haha


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.