0

Trying to create 2 objects (clients) living in different threads and communicating with 1 object(server) living on the main thread. However I'm not seeing any activity on the server object. The main goal of this code is to see how the signal slot will behave when 2 signals coming from 2 different threads are communicating with a single object on the main thread.

objects.cpp:

    #include "objects.h"

    Objects::Objects(QObject* parent): QObject (parent)
    {
    }

    void Objects::printData(const QString& data)
    {
        qDebug() << data;
    }

    void Objects::process(const QString& data)
    {
        emit sendData(data+":processed");
    }

    Q_NORETURN void Objects::run()
    {
        while (true) {
            //qDebug() << "hit" << m_rate;
            emit sendData("test"+QString::number(m_rate));
            QThread::sleep(m_rate);
        }
    }

objects.h:

    #ifndef OBJECTS_H
    #define OBJECTS_H
    #include <QObject>
    #include <QDebug>
    #include <QThread>

    class Objects: public QObject
    {
        Q_OBJECT
    public:
        explicit Objects(QObject* parent = Q_NULLPTR);

    signals:
        void sendData(const QString&);

    public slots:
        void printData(const QString&);
        void process(const QString&);
        void run();

    public:
        ulong m_rate;

    };

    #endif // OBJECTS_H

main.cpp:

#include <QCoreApplication>
#include "objects.h"

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    Objects ser;
    Objects cl1;
    Objects cl2;
    cl1.m_rate = 1;
    cl2.m_rate = 2;

    QThread cl1_t;
    QThread cl2_t;

    QObject::connect(&cl1_t, &QThread::started, &cl1, &Objects::run);
    QObject::connect(&cl2_t, &QThread::started, &cl2, &Objects::run);


    QObject::connect(&cl1, &Objects::sendData, &ser, &Objects::process);
    QObject::connect(&cl2, &Objects::sendData, &ser, &Objects::process);

    QObject::connect(&ser, &Objects::sendData, &cl1, &Objects::printData);
    QObject::connect(&ser, &Objects::sendData, &cl2, &Objects::printData);

    cl1.moveToThread(&cl1_t);
    cl2.moveToThread(&cl2_t);

    cl1_t.start();
    cl2_t.start();

    return a.exec();
}
bardao
  • 914
  • 12
  • 23
  • 1
    Why don't you use a `QTimer` with `m_rate` as the interval instead of the `while` loop? That way you won't block the event loop, you won't need the `QThread::sleep`, and your slots will be processed properly. – thuga Feb 08 '19 at 12:25

1 Answers1

1

Looks like your void run() function-member blocks Qt internal event queue. Just add QCoreApplication::processEvents(); in to your void run() and it will solve your problem.

void Objects::run()
{
    while (true) {
        qDebug() << "hit" << m_rate;
        emit sendData("test" + QString::number(m_rate));
        QThread::sleep(m_rate);
        QCoreApplication::processEvents();
    }
}

UPD: I will suggest you to read THIS wiki article for more detailed explanation on your problem.

  • any idea on how to make the signal and slot relationship unique and not have the signal emission affect 2 slots simultaneously? Can I filter before sending a signal out? – bardao Feb 09 '19 at 02:11
  • Sorry but I can’t understand what you are trying to achieve. Please provide some more information. –  Feb 11 '19 at 05:49
  • 2 threads are calling the server through 1 slot at different rates. sending a signal from 1 client will initiate 2 printData per call to the server. I'm trying to limit the communication channel between client/server to 1 response per client per call; not sure how to achieve that. – bardao Feb 11 '19 at 18:33