Search code examples
c++qtsignals-slotsqthread

Do signals create new threads?


I'm trying to understand how the signals/slots work within a GUI program. For example, if a slot in the main program gets a signal, does it create another thread to handle the slot?

mainwindow.h

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();

public slots:
    void finished_result(int);

private:
    Ui::MainWindow *ui;
    QThread* thread;
    Worker* worker;

private slots:
    void run_click();
};

mainwindow.cpp

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),ui(new Ui::MainWindow){
    ui->setupUi(this);
}

MainWindow::~MainWindow(){
    delete ui;
}

void MainWindow::run_click(){
    thread = new QThread;
    Worker* worker = new Worker();
    worker->moveToThread(thread);
    connect(worker,SIGNAL(task_finished(int)),this,SLOT(finished_result(int)));
    // all other necessary signal/slot connections
    thread->start();

    // do more stuff
}

void MainWindow::finished_result(int x){
    // do some stuff
}

In a program such as this, say the "do more stuff" take a while to process and the worker finishes the work before run_click() returns. So run_click() will be still running when task_finished(int) is emitted. Will finished_result(int) start immediately or will it wait for run_click() to finish? Will finished_result(int) start in the same thread as run_click() or in a new thread?

My particular problem is I have an unrelated QWaitCondition in my "do more stuff" which holds that thread for a while. I want my finished_result(int) to go ahead without waiting for run_click() to finish. Any ideas how to proceed? Will I need to move "do more stuff" to another worker in a new thread?


Solution

  • No, signals never create new threads.

    In your case, run_click() and finished_result(int x) will be performed in the same thread, and in this order. When the signal task_finished(int) is emitted from your worker thread, it will be transferred and wait in a queue of your main thread, waiting for run_click() to finish and hence return to the event loop. Only then finished_result(int x) will be called.

    This is called "Queued Connection" and is the default behaviour when using signals and slots accross different threads. Have a look at Threads and QObjects from the documentation for more info, in particular the section Signals and Slots Across Threads.