Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. signal and slots in Qthreadpool
Forum Updated to NodeBB v4.3 + New Features

signal and slots in Qthreadpool

Scheduled Pinned Locked Moved Unsolved General and Desktop
14 Posts 4 Posters 5.1k Views 2 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • J Offline
    J Offline
    JadeN001
    wrote on last edited by
    #1

    MyRunnable *task = new MyRunnable(socket);
    pool->start(task);
    now in MyRunnable class ,only run() method is executing in one of the thread from Qthreadpool.all other slots that is have defined in that class in executing in main thread.
    can i execute another slots in thread of Qthreadpool. if so,how ?

    kshegunovK 1 Reply Last reply
    0
    • J JadeN001

      MyRunnable *task = new MyRunnable(socket);
      pool->start(task);
      now in MyRunnable class ,only run() method is executing in one of the thread from Qthreadpool.all other slots that is have defined in that class in executing in main thread.
      can i execute another slots in thread of Qthreadpool. if so,how ?

      kshegunovK Offline
      kshegunovK Offline
      kshegunov
      Moderators
      wrote on last edited by
      #2

      Let's do it like a poll:

      Is MyRunnable a QObject?

      1. If "yes" - What is the thread affinity of that QObject?
      2. If "no" - Do regular objects have any notion of threads?

      Read and abide by the Qt Code of Conduct

      J 1 Reply Last reply
      1
      • A Offline
        A Offline
        ambershark
        wrote on last edited by
        #3

        What's in the run() function of your MyRunnable class? If it exits it will get cleaned up. If you set it to handle signals and slots you will need an event handler.

        You should post some code or explain the problem with a bit more detail as there is way too much guess work to help you solve it. :)

        My L-GPL'd C++ Logger github.com/ambershark-mike/sharklog

        J 1 Reply Last reply
        0
        • kshegunovK kshegunov

          Let's do it like a poll:

          Is MyRunnable a QObject?

          1. If "yes" - What is the thread affinity of that QObject?
          2. If "no" - Do regular objects have any notion of threads?
          J Offline
          J Offline
          JadeN001
          wrote on last edited by JadeN001
          #4

          @kshegunov yes myRunnable is QObject.
          class MyRunnable : public QObject, public QRunnable{
          };
          and for checking the thread affinity,i have write:this->thread() in both run() and slot in QRunnable class.the result i am getting is same thread value in both.
          it means mainthread value,threadaffinity value of run,threadaffinity value of slot are same , I can't understand how its happening ?

          kshegunovK 1 Reply Last reply
          0
          • A ambershark

            What's in the run() function of your MyRunnable class? If it exits it will get cleaned up. If you set it to handle signals and slots you will need an event handler.

            You should post some code or explain the problem with a bit more detail as there is way too much guess work to help you solve it. :)

            J Offline
            J Offline
            JadeN001
            wrote on last edited by JadeN001
            #5

            @ambershark
            here is my code:

            //your code here
            myserver.cpp```
            void myServer::setserver{
             socket = new QTcpSocket(this);
             qDebug() << " Client connected at " << descriptor;
            
             qDebug() << "A new socket created!";
             connect(socket, SIGNAL(readyRead()), this, SLOT(readyRead()));
            }
            void MyServer::readyRead()
            {
             
            MyTask *mytask1 = new MyTask(socket);
            connect(mytask1, SIGNAL(Result(QString)), mytask1, SLOT(TaskResult(QString)), Qt::QueuedConnection);
             qDebug() << "Starting a new task using a thread from the QThreadPool";
             QThreadPool::globalInstance()->start(mytask1);
            }
            mytask.cpp(implemented QRunnaable)
            MyTask::MyTask(QTcpSocket *s)
            {
             qDebug() << "MyTask()";
             sock=s;
            
            }
            
            void MyTask::run()
            {
            
            
             qDebug() << "Task started"<< QThread::currentThread();
             QString B= sock->readAll();
            qDebug()<<"thread affinity of run:"<<this->thread();
            
             qDebug() << "Task done";
            
            emit Result(B);
            
            }
            
            void MyTask::TaskResult(QString B)
            {
             qDebug()<<"IN WRTIING..."<<QThread::currentThread();
             QString Buffer;
              qDebug()<<"thread affinity of taskresult:"<<this->thread();
             Buffer.append("\r\nTask result = ");
             Buffer.append(B);
             sock->write(B.toStdString().c_str());
               
            }
            
            here what i am getting is :
            In run():
            qDebug() << "Task started"<< QThread::currentThread();
            o/p : QThread<0x101210,name ="thread<pooled>">
            qDebug()<<"thread affinity of run:"<<this->thread();
            o/p:thread affinity of run : QThread<0xd3800>
            
            now,in taskresult():
            qDebug()<<"IN WRTIING..."<<QThread::currentThread();
            o/p in writting : QThread<0xd3800>
            qDebug()<<"thread affinity of taskresult:"<<this->thread();
            o/p : thread affinity : QThread<0xd3800>
            
            here what i want is taskresult() run in same thread as thread of run(){QThread<0x101210,name ="thread<pooled>">}.
            A 1 Reply Last reply
            0
            • J JadeN001

              @ambershark
              here is my code:

              //your code here
              myserver.cpp```
              void myServer::setserver{
               socket = new QTcpSocket(this);
               qDebug() << " Client connected at " << descriptor;
              
               qDebug() << "A new socket created!";
               connect(socket, SIGNAL(readyRead()), this, SLOT(readyRead()));
              }
              void MyServer::readyRead()
              {
               
              MyTask *mytask1 = new MyTask(socket);
              connect(mytask1, SIGNAL(Result(QString)), mytask1, SLOT(TaskResult(QString)), Qt::QueuedConnection);
               qDebug() << "Starting a new task using a thread from the QThreadPool";
               QThreadPool::globalInstance()->start(mytask1);
              }
              mytask.cpp(implemented QRunnaable)
              MyTask::MyTask(QTcpSocket *s)
              {
               qDebug() << "MyTask()";
               sock=s;
              
              }
              
              void MyTask::run()
              {
              
              
               qDebug() << "Task started"<< QThread::currentThread();
               QString B= sock->readAll();
              qDebug()<<"thread affinity of run:"<<this->thread();
              
               qDebug() << "Task done";
              
              emit Result(B);
              
              }
              
              void MyTask::TaskResult(QString B)
              {
               qDebug()<<"IN WRTIING..."<<QThread::currentThread();
               QString Buffer;
                qDebug()<<"thread affinity of taskresult:"<<this->thread();
               Buffer.append("\r\nTask result = ");
               Buffer.append(B);
               sock->write(B.toStdString().c_str());
                 
              }
              
              here what i am getting is :
              In run():
              qDebug() << "Task started"<< QThread::currentThread();
              o/p : QThread<0x101210,name ="thread<pooled>">
              qDebug()<<"thread affinity of run:"<<this->thread();
              o/p:thread affinity of run : QThread<0xd3800>
              
              now,in taskresult():
              qDebug()<<"IN WRTIING..."<<QThread::currentThread();
              o/p in writting : QThread<0xd3800>
              qDebug()<<"thread affinity of taskresult:"<<this->thread();
              o/p : thread affinity : QThread<0xd3800>
              
              here what i want is taskresult() run in same thread as thread of run(){QThread<0x101210,name ="thread<pooled>">}.
              A Offline
              A Offline
              ambershark
              wrote on last edited by
              #6

              @JadeN001 Ok so you are connecting your slot to that Result signal on the other thread. It will be a bit of work (I think) to get it on the thread you want it on. Normally you would just call moveToThread() before connecting your signal and it would be fine. However you are using a thread pool and a fire and forget runnable with no signal handler.

              You could stop using the QRunnable and have a thread with a QEventLoop or one that you use moveToThread() and it would work how you expect. I'm just not sure how to make it work with a QRunnable and a thread pool off the top of my head. If nobody else chimes in I'll do some testing tomorrow and figure it out (when I get time).

              My L-GPL'd C++ Logger github.com/ambershark-mike/sharklog

              J 1 Reply Last reply
              2
              • A ambershark

                @JadeN001 Ok so you are connecting your slot to that Result signal on the other thread. It will be a bit of work (I think) to get it on the thread you want it on. Normally you would just call moveToThread() before connecting your signal and it would be fine. However you are using a thread pool and a fire and forget runnable with no signal handler.

                You could stop using the QRunnable and have a thread with a QEventLoop or one that you use moveToThread() and it would work how you expect. I'm just not sure how to make it work with a QRunnable and a thread pool off the top of my head. If nobody else chimes in I'll do some testing tomorrow and figure it out (when I get time).

                J Offline
                J Offline
                JadeN001
                wrote on last edited by
                #7

                @ambershark yeah thanks.i will try on it

                1 Reply Last reply
                0
                • VRoninV Offline
                  VRoninV Offline
                  VRonin
                  wrote on last edited by
                  #8

                  As stated in the docs QThreadPool can't handle slots. You'll need to use QThread instead

                  "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
                  ~Napoleon Bonaparte

                  On a crusade to banish setIndexWidget() from the holy land of Qt

                  J 1 Reply Last reply
                  3
                  • J JadeN001

                    @kshegunov yes myRunnable is QObject.
                    class MyRunnable : public QObject, public QRunnable{
                    };
                    and for checking the thread affinity,i have write:this->thread() in both run() and slot in QRunnable class.the result i am getting is same thread value in both.
                    it means mainthread value,threadaffinity value of run,threadaffinity value of slot are same , I can't understand how its happening ?

                    kshegunovK Offline
                    kshegunovK Offline
                    kshegunov
                    Moderators
                    wrote on last edited by kshegunov
                    #9

                    @JadeN001 said in signal and slots in Qthreadpool:

                    I can't understand how its happening ?

                    You should be using QThread::currentThread() and you should in that case discover that the thread run() is called into is different from the one this->thread() returns, which incidentally is the thread your slots are called in. So your original question can be answered by answering this:

                    Can I change the thread affinity of my object, i.e. call moveToThread() with the appropriate argument?

                    If the answer's yes, then you have your solution, otherwise it means it's not possible.

                    Read and abide by the Qt Code of Conduct

                    J 1 Reply Last reply
                    2
                    • kshegunovK kshegunov

                      @JadeN001 said in signal and slots in Qthreadpool:

                      I can't understand how its happening ?

                      You should be using QThread::currentThread() and you should in that case discover that the thread run() is called into is different from the one this->thread() returns, which incidentally is the thread your slots are called in. So your original question can be answered by answering this:

                      Can I change the thread affinity of my object, i.e. call moveToThread() with the appropriate argument?

                      If the answer's yes, then you have your solution, otherwise it means it's not possible.

                      J Offline
                      J Offline
                      JadeN001
                      wrote on last edited by
                      #10

                      @kshegunov i dont understand what you are trying to say.

                      kshegunovK 1 Reply Last reply
                      0
                      • J JadeN001

                        @kshegunov i dont understand what you are trying to say.

                        kshegunovK Offline
                        kshegunovK Offline
                        kshegunov
                        Moderators
                        wrote on last edited by
                        #11

                        That slots will be called in the thread a QObject is assigned to (i.e the one QObject::thread returns), which for that case is different from the thread QRunnable::run() is executed in. So to do what you're asking, you have to move the object to the thread run() is executed in. Since with QThreadPool you're not dealing with the threads themselves you don't have access to it, that means you can't do what you ask. In short what @VRonin wrote.

                        Read and abide by the Qt Code of Conduct

                        1 Reply Last reply
                        3
                        • VRoninV VRonin

                          As stated in the docs QThreadPool can't handle slots. You'll need to use QThread instead

                          J Offline
                          J Offline
                          JadeN001
                          wrote on last edited by
                          #12

                          @VRonin I want to connect multiple client to the server and want to send msg from one client to another.for this scenario i have to use qthreadpool to limit the threads.

                          VRoninV 1 Reply Last reply
                          0
                          • J JadeN001

                            @VRonin I want to connect multiple client to the server and want to send msg from one client to another.for this scenario i have to use qthreadpool to limit the threads.

                            VRoninV Offline
                            VRoninV Offline
                            VRonin
                            wrote on last edited by
                            #13

                            @JadeN001 said in signal and slots in Qthreadpool:

                            for this scenario i have to use qthreadpool to limit the threads.

                            Not really, you just have to do some more manual work.

                            You can reimplement QTcpServer::incomingConnection to something like this:

                            void incomingConnection(qintptr socketDescriptor) override
                            {
                                /*
                                const int m_idealThreadCount = qMax(QThread::idealThreadCount(),1);
                                QVector<QThread*> m_availableThreads;
                                QVector<int> m_threadsLoad;
                                */
                                QTcpSocket* newSocket = new QTcpSocket(this);
                                newSocket->setSocketDescriptor(socketDescriptor);
                                int threadIdx = m_availableThreads.size();
                                if (threadIdx<m_idealThreadCount) { //we can add a new thread
                                    m_availableThreads.append(new QThread(this));
                                    m_threadsLoad.append(1);
                                    m_availableThreads.last()->start();
                                }
                                else{
                                    // find the thread with the least amount of clients and use it
                                    threadIdx = std::distance(m_threadsLoad.cbegin(),std::min_element(m_threadsLoad.cbegin(), m_threadsLoad.cend()));
                                    ++m_threadsLoad[threadIdx];
                                }
                                newSocket->moveToThread(m_availableThreads.at(threadIdx));
                                connect(newSocket, &QTcpSocket::disconnected, newSocket, &QTcpSocket::deleteLater);
                                connect(newSocket, &QTcpSocket::disconnected, this, [this, threadIdx]() {--m_threadsLoad[threadIdx];});
                                // connect other stuff to use the socket
                                addPendingConnection(newSocket);
                            }
                            

                            "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
                            ~Napoleon Bonaparte

                            On a crusade to banish setIndexWidget() from the holy land of Qt

                            J 1 Reply Last reply
                            2
                            • VRoninV VRonin

                              @JadeN001 said in signal and slots in Qthreadpool:

                              for this scenario i have to use qthreadpool to limit the threads.

                              Not really, you just have to do some more manual work.

                              You can reimplement QTcpServer::incomingConnection to something like this:

                              void incomingConnection(qintptr socketDescriptor) override
                              {
                                  /*
                                  const int m_idealThreadCount = qMax(QThread::idealThreadCount(),1);
                                  QVector<QThread*> m_availableThreads;
                                  QVector<int> m_threadsLoad;
                                  */
                                  QTcpSocket* newSocket = new QTcpSocket(this);
                                  newSocket->setSocketDescriptor(socketDescriptor);
                                  int threadIdx = m_availableThreads.size();
                                  if (threadIdx<m_idealThreadCount) { //we can add a new thread
                                      m_availableThreads.append(new QThread(this));
                                      m_threadsLoad.append(1);
                                      m_availableThreads.last()->start();
                                  }
                                  else{
                                      // find the thread with the least amount of clients and use it
                                      threadIdx = std::distance(m_threadsLoad.cbegin(),std::min_element(m_threadsLoad.cbegin(), m_threadsLoad.cend()));
                                      ++m_threadsLoad[threadIdx];
                                  }
                                  newSocket->moveToThread(m_availableThreads.at(threadIdx));
                                  connect(newSocket, &QTcpSocket::disconnected, newSocket, &QTcpSocket::deleteLater);
                                  connect(newSocket, &QTcpSocket::disconnected, this, [this, threadIdx]() {--m_threadsLoad[threadIdx];});
                                  // connect other stuff to use the socket
                                  addPendingConnection(newSocket);
                              }
                              
                              J Offline
                              J Offline
                              JadeN001
                              wrote on last edited by JadeN001
                              #14

                              @VRonin yeah thanks i willgo through it.for better understanding ,can you provide any example in which this approach is used.

                              1 Reply Last reply
                              0

                              • Login

                              • Login or register to search.
                              • First post
                                Last post
                              0
                              • Categories
                              • Recent
                              • Tags
                              • Popular
                              • Users
                              • Groups
                              • Search
                              • Get Qt Extensions
                              • Unsolved