Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

QThreadPool reserveThread example

Tags:

qt

pyside

Can anyone provide an example of using "reserveThread" and/or "releaseThread" from the QThreadPool class? I have read the documentation, but I don't really understand when you would use these functions. Internet searches for examples have come up empty.

I am using PySide, so Python would be preferred, but C++ is also good.

like image 391
Becca codes Avatar asked Aug 15 '16 16:08

Becca codes


People also ask

What is QThreadPool?

QThreadPool manages and recycles individual QThread objects to help reduce thread creation costs in programs that use threads. Each Qt application has one global QThreadPool object, which can be accessed by calling globalInstance().

How do you stop QThreadPool?

The simple solution is to subclass QThreadPool and add an aboutToWait signal to that class. The signal would need to be emitted in the destructor. You can then hook up the signal to the controller's cancelAll() slot. For this to work, the pool must be declared after the workers list!

How do you stop Qrunnable?

What you want to do is make your background task a QObject, give it a run() slot, and connect the thread. started to the worker. run. That's what will kick the process off.


1 Answers

These methods are used to interoperate the thread pool with threads that you manually manage.

The thread pool keeps a count of active threads and aims for it not to exceed the maximum number of threads that make sense on given hardware. The reserveThread and releaseThread change the number of active threads that the pool is aware of. It doesn't directly add nor remove any threads from the pool. It's not an error that these methods don't return a QThread.

reserveThread means: "I'm using a thread that I manage elsewhere, so please consider my thread to be active even though it's not yours (thread pool's).

releaseThread means: "I'm not using my thread anymore, feel free to make more of your threads active."

Example: Consider a four logical CPU system. Code is C++.

  1. Initially:

    QThreadPool pool;
    assert(pool.maxThreadCount() == 4);
    assert(pool.activeThreadCount() == 0);
    
  2. You start a dedicated calculation thread: one core becomes busy. You inform the pool by calling reserveThread:

    MyWorker worker;
    QThread thread;
    worker.moveToThread(&thread);
    thread.start();
    pool.reserveThread();
    assert(pool.activeThreadCount() == 1);
    

    The pool is not running any threads itself!

  3. You submit four runnables, each taking a while. The pool creates three additional threads to execute them:

    QAtomicInt act = 0;
    QtConcurrent.run(&pool, [&]{ act.ref(); QThread::sleep(60); act.deref();  });
    QtConcurrent.run(&pool, [&]{ act.ref(); QThread::sleep(60); act.deref();  });
    QtConcurrent.run(&pool, [&]{ act.ref(); QThread::sleep(60); act.deref();  });
    QtConcurrent.run(&pool, [&]{ act.ref(); QThread::sleep(60); act.deref();  });
    QThread::sleep(1);
    assert(pool.activeThreadCount() == 4);
    assert(act.load() == 3);
    

    Only three runnables are now active, since one out of four threads is reserved and can't be active: it'd have no CPU to run on, since your thread is busy there.

  4. Your calculation thread is done, and you free up one core. You inform the pool by calling releaseThread:

    thread.quit();
    thread.wait();
    pool.releaseThread();
    QThread::sleep(1);
    assert(pool.activeThreadCount() == 4);
    assert(act.load() == 4);
    

    Since there was an extra runnable waiting, a thread was activated to get the runnable going.

  5. After a minute, all the runnables are done, and there are no more active threads:

    QThread::sleep(60);
    assert(pool.activeThreadCount() == 0);
    assert(act.load() == 0);
    
like image 65
Kuba hasn't forgotten Monica Avatar answered Nov 15 '22 07:11

Kuba hasn't forgotten Monica