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
-
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 :)
-
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?
-
@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?
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------------------
-
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------------------
@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.