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



  • 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


  • Lifetime Qt Champion

    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.



  • 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 :)



  • @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?



  • @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.



  • 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------------------
    

  • Qt Champions 2016

    @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.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.