Correct way to signal QObject on another thread?

Viewed 1399

Let's say I have a slave object that lives in another thread. I want to tell it to do A, B, C on that thread. I can think of 3 ways of doing it:

(1) Using QTimer::singleShot

(2) Using QMetaObject::invokeMethod

(3) Creating another master object and connecting its signal to the slave

Following is an example:

class slave : public QObject
{
    QThread thread_;

    friend class master;
    void do_A(params);
    void do_B(params);
    void do_C(params);

public:
    slave() { thread_.start(); moveToThread(&thread_); }
    ~slave() { thread_.quit(); thread_.wait(); }

    void que_A(params) { QTimer::singleShot(0, [&](){ do_A(params); }); } // (1)

    void que_B(params) { QMetaObject::invokeMethod(this, "do_B", params); } // (2)
}

class master : public QObject // (3)
{
    Q_OBJECT

public:
    master(slave* s) { connect(this, &master::que_C, s, &slave::do_C); }

    void do_C(params) { emit que_C(params); }

signals:
    void que_C(params);
}

My concerns are:

(1) I am abusing QTimer.

(2) Using strings for signals/slot is so qt4. Qt5 uses new syntax.

(3) Too much boilerplate.

Is any of the methods considered more correct compared to the others? Or can anybody think of a better way?

Please include your reasoning (not just opinion) why one method should be chosen over others.

UPDATE:

In my real-world application I have another class -- let's call it owner -- that owns several slaves. The owner needs to tell different slaves to do different things (A, B or C) depending on user input. The slaves are stateful objects, so I cannot see an easy way of using concurrency functions (eg, std::async or QtConcurrency).

3 Answers
Related