July 27, 2011

yan bellavance yan bellavance
Lab Rat
66 posts

discussion about threads, moveToThread etc.

Page  
1

peppe wrote:
Well, do you know of a better API you can use instead of Sleep()? You could patch QThread::sleep () and submit a MR :)

if you want to let the GUI to keep doing its while it waits then call QCoreApplication::processEvents()

if you really need to sleep because you have other code you want to run then just do it in a qthread and call moveToThread. I have done it and it works very well.

EDIT: split of of this thred: Poor QThread::sleep() and ::usleep() resolution on Windows [developer.qt.nokia.com] , Gerolf

63 replies

July 27, 2011

LinusA LinusA
Lab Rat
69 posts

yan bellavance wrote:

if you want to let the GUI to keep doing its while it waits then call QCoreApplication::processEvents()

Doing this, no problem, all fine. Though processEvents() is some sort of “the opposite” of sleep(), I still call it during my display loop to keep the GUI responsive.

yan bellavance wrote:

if you really need to sleep because you have other code you want to run then just do it in a qthread and call moveToThread. I have done it and it works very well.

Doing this. But tell me: I’ve got a worker thread doing stuff. It waits for hardware. It needs to poll. I would like to sleep between polling, but not for 15ms, more like 0.1ms (so I don’t miss when my hardware is ready). How would I do this?

July 27, 2011

yan bellavance yan bellavance
Lab Rat
66 posts

Well one thing I might have forgotten to mention is that I don’t call exec in that QThread so It actually does not have an eventloop because I have implemented a polling technique. Just put a forever loop in your run function and call QThread::sleep ::msleep ::usleep from there. here is a small example:

  1. //the timeout periods are multiples of the delay period for consistency.  I dont
  2. //need that much accuracy but if I did I woull read a timer and do the delta
  3. //time of each loop
  4. void myQthread::run()
  5. {
  6.     //do init stuff here.  you could call moveTothread either in constructor of
  7.     //qthread or at the end of you init in the run function but before the forever loop.
  8.  
  9.     forever{
  10.         this->msleep(delay);
  11.         doLogsTimeout-=delay;
  12.         clockUpdTimeout-=delay;
  13.         tduRefreshTimeout-=delay;
  14.        
  15.         if(doLogsTimeout<=0){
  16.             doLogsTimeout = LOGS_TIMEOUT_PERIOD;
  17.             //....do what you need to do here
  18.         }
  19.         if(clockUpdTimeout<=0){
  20.             clockUpdTimeout = CLOCKUPD_TIMEOUT_PERIOD;
  21.             //....do what you need to do here
  22.         }
  23.         if(tduRefreshTimeout<=0){
  24.             tduRefreshTimeout = TDUREFRESH_TIMEOUT_PERIOD;
  25.             //....do what you need to do here
  26.         }
  27.     }
  28. }

July 27, 2011

Gerolf Gerolf
Robot Herder
3253 posts
yan bellavance wrote:
Well one thing I might have forgotten to mention is that I don’t call exec in that QThread so It actually does not have an eventloop because I have implemented a polling technique. Just put a forever loop in your run function and call QThread::sleep ::msleep ::usleep from there.

If you have read the thread completly, this is what he wants to do and what (on windows) has the 15 mSec resolution. This is not due to Qt it’s due to windows. And he want’s to do not busy waiting, so sleep would be great but has the resolution problem on WINDOWS.

 Signature 

Nokia Certified Qt Specialist.
Programming Is Like Sex: One mistake and you have to support it for the rest of your life. (Michael Sinz)

July 27, 2011

yan bellavance yan bellavance
Lab Rat
66 posts

Gerolf wrote:

If you have read the thread completly, this is what he wants to do and what (on windows) has the 15 mSec resolution. This is not due to Qt it’s due to windows. And he want’s to do not busy waiting, so sleep would be great but has the resolution problem on WINDOWS.

I wrote that because i was referring to:

peppe wrote:
I still think that using sleep() in any code is usually wrong

And also referring to other thread that discourage the use of sleep. I want to make evident that if moveToThread is not called then calling sleep from the QThread is actually done from the main thread and can make the GUI freeze. So I am not fixing the delay resolution issue but am trying to help him make things safer. Also I was hoping this would at least give him more constance in the sleep resolution.

July 27, 2011

Gerolf Gerolf
Robot Herder
3253 posts

If you don’t use moveToThread, you can also call sleep inside a worker thread, that has no influence in general. Inside QThread::run you can call sleep and it will be inside the worker thread.

Call sleep in the main thread might have som unexpected result to some users as the UI freezes and mostly it is said: don’t call sleep in main thread.

 Signature 

Nokia Certified Qt Specialist.
Programming Is Like Sex: One mistake and you have to support it for the rest of your life. (Michael Sinz)

July 27, 2011

yan bellavance yan bellavance
Lab Rat
66 posts

if you dont moveToThread then the worker thread and GUI thread share the same event loop and that can cause problems. For example: calling QUdpSocket polling functions such as waitForReadyRead() and waitForBytesWritten()

July 27, 2011

Gerolf Gerolf
Robot Herder
3253 posts

that depends where you call them. and a thread only has an event loop, if you run it. If you implement everything inside the thread’s run method, and do “normal” stuff there, all works. I do that all the time, without an event loop and without moveToThread. It just depends, where you create the object. If you create them inside run, all is fine. The currently active thread during object creation is the needed information. So create the QUdpSocket inside run, it works.

EDIT: if you create the objects inside the QThread’s constructor, the are attached to the creating thread, not the QTHread object

 Signature 

Nokia Certified Qt Specialist.
Programming Is Like Sex: One mistake and you have to support it for the rest of your life. (Michael Sinz)

July 27, 2011

peppe peppe
Ant Farmer
1028 posts
yan bellavance wrote:
You have to be carefull when people tell you not to call a function because it’s “dangerous”. If we listen to them then we cannot call: QCoreApplication::processEvents(), QThread::sleep(), QObject::moveToThread() or others I have not read of. They say this because of the context in which they are programming, they have guidelines that limit what they can do.

This thread has NOTHING to do with those methods. And nobody said that it’s dangerous. Only that they lead to bad/fragile code.

Of course you should never call sleep() in the GUI main thread (if you don’t moveToThread() your QThread then it’s still in the main thread and then I would see why calling sleep should be avoided) and if you call processEvents(), do it from the GUI main thread preferably.

… you CAN’T call QThread::sleep from the main thread, since you don’t have access to that QThread protected sleep() …

I built a qt app on Linux that uses all of these and it’s been running for a year now without ever crashing. Also, my app often show its CPU usage as 0% in the system monitor (on windows this would be windows task manager),its very efficient. I do have an i7 intel cpu.

And we’re talking about Windows.

yan bellavance wrote:
peppe wrote:
Well, do you know of a better API you can use instead of Sleep()? You could patch QThread::sleep () and submit a MR :)

if you want to let the GUI to keep doing its while it waits then call QCoreApplication::processEvents()

if you really need to sleep because you have other code you want to run then just do it in a qthread and call moveToThread. I have done it and it works very well.

This reply is nonsense — I was talking about QThread::sleep resolution on Windows. That is, the OP’s issue.

 Signature 

Software Engineer
KDAB (UK) Ltd., a KDAB Group company

July 27, 2011

yan bellavance yan bellavance
Lab Rat
66 posts

Gerolf wrote:
that depends where you call them. and a thread only has an event loop, if you run it. If you implement everything inside the thread’s run method, and do “normal” stuff there, all works. I do that all the time, without an event loop and without moveToThread. It just depends, where you create the object. If you create them inside run, all is fine. The currently active thread during object creation is the needed information. So create the QUdpSocket inside run, it works.

EDIT: if you create the objects inside the QThread’s constructor, the are attached to the creating thread, not the QTHread object

if you call moveToThread and dont run exec() you do not have an event loop therefore if you have a something like a qtimer in your qthread it won’t emit signals and you wont be able to trigger slots connected its signals. There actually used to be a warning about not calling waitForReadyRead and waitForBytesWritten from the main thread as it could make the app crash. I have tried it even inside a qthread and seen this happen and once i used moveToThread, it went away.

July 27, 2011

Gerolf Gerolf
Robot Herder
3253 posts
yan bellavance wrote:
if you call moveToThread and dont run exec() you do not have an event loop therefore if you have a something like a qtimer in your qthread it won’t emit signals and you wont be able to trigger slots connected its signals. There actually used to be a warning about not calling waitForReadyRead and waitForBytesWritten from the main thread as it could make the app crash. I have tried it even inside a qthread and seen this happen and once i used moveToThread, it went away.

And where did you create the object? I assume in the QThread’s constructor. I did not say that signal/slot work without event loop, but it totally works without moveToThread if you create the objects correctly.

see peppes wiki article [developer.qt.nokia.com]

 Signature 

Nokia Certified Qt Specialist.
Programming Is Like Sex: One mistake and you have to support it for the rest of your life. (Michael Sinz)

July 27, 2011

yan bellavance yan bellavance
Lab Rat
66 posts

just tried it and it ain’t working. Got a bunch of these messages:

Warning: QObject: Cannot create children for a parent that is in a different thread.

Of course I can emit signals form the qthread and connect them to slots in the main thread but what you speak of requires the opposite. Anyway I think I just spammed this thread. Sorry about that but it was a discussion in which I learned something from everyone.

July 28, 2011

Andre Andre
Robot Herder
6399 posts

The cause of that is simple. Objects created in thread B can not have an object in thread A as their parent. So, the first object that you create in the run() method of your QThread, can not have any parent, as there is no QObject available in the same thread that can be used for that. Any following object can get the first object as parent, if that makes sense in your case.

So: you have to make sure you delete the created object yourself at an appropriate time.

July 28, 2011

Gerolf Gerolf
Robot Herder
3253 posts
Andre wrote:
So: you have to make sure you delete the created object yourself at an appropriate time.

The easiest way to achieve this is to create the first object as object on the stack, and put all other as children of it, Then everything will be deleted correctly :-)

 Signature 

Nokia Certified Qt Specialist.
Programming Is Like Sex: One mistake and you have to support it for the rest of your life. (Michael Sinz)

July 28, 2011

peppe peppe
Ant Farmer
1028 posts

Can we please split this thread? It definitely went offtopic.

 Signature 

Software Engineer
KDAB (UK) Ltd., a KDAB Group company

July 28, 2011

yan bellavance yan bellavance
Lab Rat
66 posts

/agree. Is there a way to split a thread? guess so :)

Page  
1

  ‹‹ [SOLVED] Qt Meta-Obect System: QObject::setProperty() with QVariant user defined types - fails      Sending Signals to Non-Qt-Thread - How? ››

You must log in to post a reply. Not a member yet? Register here!