Qt Forum

    • Login
    • Search
    • Categories
    • Recent
    • Tags
    • Popular
    • Users
    • Groups
    • Search
    • Unsolved

    Update: Forum Guidelines & Code of Conduct


    Qt World Summit: Early-Bird Tickets

    Solved QThread as memeber class doing an infinite loop until threads die.

    General and Desktop
    4
    7
    1983
    Loading More Posts
    • 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.
    • A
      aurquiel last edited by aurquiel

      Hello i am creating two threads inside another thread, thread 1 is the father of thread 2 and thread 3

      The only function of thread1 is to separate thread2 y thread3 form the main thread (Window thread).

      I have the need to create thread 2 and thread 3 because the are going to receive data and there are going to write it in a file almost in simultaneously way, if a put the write function only in thread1 is going to be to slow and i will lost packets .

      The problem i have if how to put in an infinite loop of reading and writing the thread2 and thread3

      Look to the code i wrote

      //star a thread for moving out main thread
      void backend::strating_thread()
      {
          //put functions into the thread
          moveToThread(&one);
          //When thread started execute this slots
          connect(&one, SIGNAL(started()), this, SLOT(cicle_transfer()));
          //Starting thread one
          one.start();
      }
      
      //Transfering and filling
      void backend::cicle_transfer()
      {
          //put functions into the thread
          moveToThread(&two);
          moveToThread(&three);
      
          //When thread started execute this slots
          connect(&two, SIGNAL(started()), this, SLOT(transfer_thread()));
          connect(&three, SIGNAL(started()), this, SLOT(transfer_thread_2()));
      
          //keep doing until thread one die
          while (1)
          {
              //Begins threads
              two.start();        //Thread two star
              three.start();      //Thread three star
          }
      
      }
      
      void backend::transfer_thread()
      {
          //Creating in the heap buffer to receive 245760 bytes= 240 Kb
          unsigned int len=245760;
          unsigned char *MPEG2_TS= new unsigned char[len];
      
          //It's a return of libusb_interrupt_transfer with the number of bytes that were transferred
          int transferred=0;
      
          //It's a return of libusb_interrupt_transfer return 0 if the transfer was successful
          int resultado=0;
      
          //Receiving Transfer
          resultado=libusb_interrupt_transfer (device_handle,   //The device handle
                                          0x82,                 //Endponit 2
                                          MPEG2_TS,            //Buffer
                                          len,                  //Size of Buffer
                                          &transferred,         //Return the number of bytes transferred
                                          0                     //waiting time to receive the answer
                                        );
      
          if (resultado!=0) error=10;   //For error 10: "Error in transfer in thread one"
      
          //Function to write to the circular buffer
          mutex.lock();
          write_file(MPEG2_TS,len);
          mutex.unlock();
      }
      
      
      void backend::transfer_thread_2()
      {
          //Creating in the heap buffer to receive 245760 bytes= 240 Kb
          unsigned int len=245760;
          unsigned char *MPEG2_TS= new unsigned char[len];
      
          //It's a return of libusb_interrupt_transfer with the number of bytes that were transferred
          int transferred=0;
      
          //It's a return of libusb_interrupt_transfer return 0 if the transfer was successful
          int resultado=0;
      
          //Receiving Transfer
          resultado=libusb_interrupt_transfer (device_handle,   //The device handle
                                          0x82,                 //Endponit 2
                                          MPEG2_TS,             //Buffer
                                          len,                  //Size of Buffer
                                          &transferred,         //Return the number of bytes transferred
                                          0                     //waiting time to receive the answer
                                        );
      
          if (resultado!=0) error=11;   //For error 11: "Error in transfer in thread two"
      
          //Function for write in the file
          mutex.lock();
          write_file(MPEG2_TS,len);
          mutex.unlock();
      }
      
      //-----------------------FUNCTIONS FOR THREADS AND CREATING FILE END------------------
      

      In a part of my program i called strating_thread() this part will connect thread1 (father) to the slot cicle_transfer() functions , when thread1 star cicle_transfer() will create connections to transfer_thread() for thread2 and transfer_thread_2() for thread3.

      Well transfer_thread() and transfer_thread_2() will receive data through a usb transfer, the explanation of this two thread is while one of then is writing to the file the other will receive data in a simultaneous way.

      I could create the file but which two transfer successful an i thinking is because of this

          //keep doing until thread one die
          while (1)
          {
              //Begins threads
              two.start();        //Thread two star
              three.start();      //Thread three star
          }
      

      When i execute it the output

      QObject::moveToThread: Current thread (0x55d8b51f3d80) is not the object's thread (0x55d8b51f3d90).
      Cannot move to target thread (0x55d8b51f3da0)
      

      The file fills whit 480KB only

      1 Reply Last reply Reply Quote 0
      • SGaist
        SGaist Lifetime Qt Champion last edited by

        Hi,

        That looks very complicated and wrong. In this case, why not subclass QThread and implement a controlled infinite loop in the run method that goes read the usb and write to the file ?

        If the writing doesn't happen fast enough you'll have a problem at some point anyway but if it's only a matter of slowness pick you can use a buffer and have a second thread writing to the file but again using a subclass of QThread.

        Interested in AI ? www.idiap.ch
        Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

        1 Reply Last reply Reply Quote 0
        • J.Hilk
          J.Hilk Moderators last edited by

          this, doesn't seem correct.

          You dotn have to create a thread to creat 2 new threads.

          I suggest the following:

          Seperate your receive and write functions in 2 seperate classes.

          classReceive;
          classWrite;
          

          during startup, create 2 Threads and one instance of each of your classes:

          QThread threadReceive;
          QThread threadWrite;
          
          classRecieve *cReceive = new classRecieve();
          classWrite *cWrite = new classWrite();
          

          move your classes to the threads and start them

          cReceive->moveToThread(&threadReceive);
          cWrite->moveToThread(&threadWrite);
          
          threadReceive.start();
          threadWrite.start();
          

          Handle your datatransfer with Signal & Slots

          connect(cReceive, &classRecieve::NewData; cWrite, &classWrite::WriteData);
          

          You can subclass QThread like SGaist suggests, but that has ben declared as not the optimal way to handle threads, although it may or may not be written differently in the docu :)

          Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct

          Qt Needs YOUR vote: https://bugreports.qt.io/browse/QTQAINFRA-4121


          Q: What's that?
          A: It's blue light.
          Q: What does it do?
          A: It turns blue.

          A 1 Reply Last reply Reply Quote 0
          • A
            aurquiel @J.Hilk last edited by

            @J.Hilk said in QThread as memeber class doing an infinite loop until threads die.:

            this, doesn't seem correct.

            You dotn have to create a thread to creat 2 new threads.

            I suggest the following:

            Seperate your receive and write functions in 2 seperate classes.

            classReceive;
            classWrite;
            

            during startup, create 2 Threads and one instance of each of your classes:

            QThread threadReceive;
            QThread threadWrite;
            
            classRecieve *cReceive = new classRecieve();
            classWrite *cWrite = new classWrite();
            

            move your classes to the threads and start them

            cReceive->moveToThread(&threadReceive);
            cWrite->moveToThread(&threadWrite);
            
            threadReceive.start();
            threadWrite.start();
            

            Handle your datatransfer with Signal & Slots

            connect(cReceive, &classRecieve::NewData; cWrite, &classWrite::WriteData);
            

            You can subclass QThread like SGaist suggests, but that has ben declared as not the optimal way to handle threads, although it may or may not be written differently in the docu :)

            Let me explain what i understood

            The classreceive always going to be filling the buffer receiving always, its just a signal that says buffer fills or transfer receiving then call the slot in classwirte to write in the file, doing the reading and writing in different threads, just a have the doubt what happen if the writing is too slow how i could solve this?

            J.Hilk 1 Reply Last reply Reply Quote 0
            • J.Hilk
              J.Hilk Moderators @aurquiel last edited by

              @aurquiel

              Tdoing the reading and writing in different threads, just a have the doubt what happen if the writing is too slow how i could solve this?

              You don't have to worry too much,

              CrossThread Signal/Slots are Queued, if the Write function is not jet done, it will wait with the next set until it is done.

              You'll most likly run out of memory before Signals are lost. But to make sure, you could always append your Data to a buffer, and depend your write functions on the buffer.

              Also, the most time will take opening/closing the file, so keep it open untill everything is received.

              Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct

              Qt Needs YOUR vote: https://bugreports.qt.io/browse/QTQAINFRA-4121


              Q: What's that?
              A: It's blue light.
              Q: What does it do?
              A: It turns blue.

              1 Reply Last reply Reply Quote 0
              • A
                aurquiel last edited by aurquiel

                I am having a problem moving the objects to the thread.

                 //Threads for write and receive usb transfer
                    QThread *threadReceive = new QThread();
                    QThread *threadWrite = new QThread();
                
                
                    //Objects of the class receive and write
                    receive *receive_usb = new receive;
                    write *write_to_file = new write;
                
                    //passing the usb handle deveice
                    receive_usb->device_handle_receive=usb_channels->device_handle;
                
                    //Move to threads
                    receive_usb->moveToThread(threadReceive);
                    write_to_file->moveToThread(threadWrite);
                
                    //Strat the threads
                    threadReceive->start();
                    threadWrite->start();
                
                    //connect(receive_usb,SIGNAL(), write_to_file, SLOT());
                
                /home/pasante/Escritorio/PIZZA_FILE/mainwindow.cpp:78: error: ‘class receive’ has no member named ‘moveToThread’
                     receive_usb->moveToThread(threadReceive);
                                  ^~~~~~~~~~~~
                

                Of course the receive class doens't have any function called moveToThread() i tried to include Qthread and mainwindow.h but not work

                for now this is my receive class

                header

                #ifndef RECEIVE_H
                #define RECEIVE_H
                #include <libusb-1.0/libusb.h> //Include libsub
                
                class receive
                {
                public:
                    receive();
                    libusb_device_handle *device_handle_receive;
                private:
                    //Creating in the heap buffer to receive 245760 bytes= 240 Kb
                    unsigned char MPEG2_TS[245760];
                
                    //-----------PRIVATE FUNCTIONS BEGIN-------------
                    void transfer_usb(); //recieving tranfer from USB
                    //-----------PRIVATE FUNCTIONS END---------------
                
                signals:
                    void sended(unsigned char *MPEG2_TS);
                
                };
                
                #endif // RECEIVE_H
                
                

                main

                #include "receive.h"
                
                receive::receive()
                {
                
                }
                
                //-----------------------FUNCTION FOR USB RECEIVING BEGIN----------------
                
                void receive::transfer_usb()
                {
                    //It's a return of libusb_interrupt_transfer with the number of bytes that were transferred
                    int transferred=0;
                
                    //It's a return of libusb_interrupt_transfer return 0 if the transfer was successful
                    int resultado=0;
                
                    //Receiving Transfer
                    resultado=libusb_interrupt_transfer (device_handle_receive,   //The device handle
                                                    0x82,                 //Endponit 2
                                                    MPEG2_TS,             //Buffer
                                                    245760,               //Size of Buffer
                                                    &transferred,         //Return the number of bytes transferred
                                                    0                     //waiting time to receive the answer
                                                  );
                
                    if (resultado!=0) error=10;   //For error 10: "Error in transfer in thread one"
                    sended(MPEG2_TS);
                }
                
                void receive::sended(unsigned char *MPEG2_TS)
                {
                    emit sended(MPEG2_TS);
                }
                
                //-----------------------FUNCTION FOR USB RECEIVING END------------------
                
                kshegunov 1 Reply Last reply Reply Quote 0
                • kshegunov
                  kshegunov Moderators @aurquiel last edited by

                  @aurquiel said in QThread as memeber class doing an infinite loop until threads die.:

                  Of course the receive class doens't have any function called moveToThread() i tried to include Qthread and mainwindow.h but not work

                  To be able to move an object to a thread, that object must be a QObject subclass.

                  Read and abide by the Qt Code of Conduct

                  1 Reply Last reply Reply Quote 1
                  • First post
                    Last post