QThread FAQ in Interviews

Q) What is the entry point for qthread?
The run() implementation is for a thread what the main() entry point is for the application.
Q) Different types of thread?
http://blog.debao.me/2013/08/how-to-use-qthread-in-the-right-way-part-1/
http://ynonperek.com/course/qt/threads.html
First:
QThread MyThread;
this->moveToThread(&MyThread);
//”this” makes object of current class to run in thread
MyThread.start();
Second:
Subclass Qthread and override run()
Third:
QtConcurrent::run(this, &Camera::firstStartThreadProc);
OR
QFuture<void> f1 = QtConcurrent::run(this, &CanDTC::readThreadProc);
USAGE-01
#include <QtCore>
class Thread : public QThread
{
private:
    void run()
    {
        qDebug()<<"From worker thread: "<<currentThreadId();
    }
};
int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    qDebug()<<"From main thread: "<<QThread::currentThreadId();

    Thread t;
    QObject::connect(&t, SIGNAL(finished()), &a, SLOT(quit()));

    t.start();
    return a.exec();
}

Q) What happens if Qthread subclas declartion is in cpp and anot in header file?
You need to have a line at the bottom of your source file: #include "main.moc"
That's because the declaration of class Thread isn't in a header - it's in a .cpp file. So by default moc won't run on it. Adding the line does two things:
it signals to qmake and moc that moc has to process the .cpp file
it causes the stuff that moc generates to be pulled in by the compile step
So after adding that line you'll need to rerun qmake so it can update the makefiles to cause main.moc to be generated.

Q) What is the difference between QueuedConnection and normal connection in connect Qt?
// connect signal-slots for decoupling
QObject::connect (this, SIGNAL(setCurrentTaskSignal(int)), this,
    SLOT(SetCurrentTaskSlot(int)), Qt::QueuedConnection);
Note that QueuedConnection doesn't mean that something is in different thread. QueuedConnection means only that when signal is emitted, corresponding slot won't be called directly. It will be queued on event loop, and will be processed when control will be given back to event loop
One uses a queued connection to ensure that the signal will be delivered from within the event loop, and not immediately from the emit site as happens with direct connection. Direct connection is conceptually a set of calls to function pointers on a list. Queued connection is conceptually an event sent to a clever receiver who can execute a function call based on the contents of the event.

Qt.QueuedConnection -> When emitted, the signal is queued until the event loop is able to deliver it to the slot.

Qt.BlockingQueuedConnection -> Same as QueuedConnection, except that the current thread blocks until the slot has been delivered. This connection type should only be used for receivers in a different thread. Note that misuse of this type can lead to dead locks in your application.

Direct signal-slot connection is nothing else but a chain of synchronous or direct C++ function calls.
A queued signal-slot connection is nothing else but an asynchronous function call

Q) When is Qthread begin executing?
QThreads begin executing in run().
By default, run() starts the event loop by calling exec()...".

Q) By whom and when is run() method called in Qthread?
The run() method is called automagically by Qt when the caller calls start() on your thread

Q) How qthread can be used?
To be able to use one of the QThreadPool threads, we have to subclass QRunnable and implement the run() method. After that, we have to create an instance of the QRunnable subclass and pass it to QThreadPool::start().
//start->run->qthread.

Q)Wtat is the main difference between a process and a thread?
The main difference between a process and a thread is that each process is executed in a separate address space, whereas each thread uses the same address space of a process.
A process can have multiple threads.
Threads share the heap, but each thread of execution has its own call stack.

Q) Difference between QThread runnable and QtConcurrent?
QThread provides a low-level class that can be used for explicit creation of long-running threads.
Using QtConcurrent's functional map/filter/reduce algorithms, which apply functions in parallel to each item in a container, you can write a program that automatically takes advantage of the system's multiple cores by distributing the processing across the threads managed by the thread pool. Alternatively, you can use QRunnable as a base class for the Command pattern and schedule work with QtConcurrent::run(). In these cases, you do not need to create threads explicitly or manage them directly – you can simply describe the pieces of work as objects with the right interface.
QtConcurrent runs a pool of threads and it is a higher level API not well-suited to run a large number of blocking operations:
If you have CPU-bound work to do and want to distribute it across multiple cores, you can break up your work into QRunnables and make those thread-safe by following these recomendations.
Distribute the CPU-heavy calculations across multiple threads using QtConcurrent algorithms whenever possible, instead of writing your own QThread code.
Do not access the GUI (this includes any QWidget-derived class, QPixmap, and other graphics-card specific classes) from any thread other than the main thread. This includes read access like querying the text entered into a QlineEdit.

Q) Suppose your application needs to run a function in multiple threads the number of which is more than the number of CPU cores/threads.
 One way is to use QtConcurrent and setting the maximum thread count :
MyClass *obj = new MyClass;
QThreadPool::globalInstance()->setMaxThreadCount(30);
for(int i=0;i<30;i++)
    QtConcurrent::run(obj, &MyClass::someFunction);
Another way is to have multiple objects and move them to different threads using moveToThread :
for(int i=0;i<30;i++)
{
        MyClass *obj = new MyClass;
        QThread *th = new QThread();
        obj->moveToThread(th);
        connect(th, SIGNAL(started()), obj, SLOT(someFunction()) );
        connect(obj, SIGNAL(workFinished()), th, SLOT(quit()) );
        connect(th, SIGNAL(finished()), obj, SLOT(deleteLater()) );
        connect(th, SIGNAL(finished()), th, SLOT(deleteLater()) );
        th->start();
}

No comments:

Post a Comment