Pausing a QThread
-
Yesterday somebody asked whether they could pause a secondary
QThread
. Until I looked I had assumed they could, but there is noQThread::pause()
. Given that both Linux & Windows do have a "thread pause" function, out of idle curiosity does anybody know why Qt does not offer this?[P.S. Note that even
QFuture::setPaused(true)
cannot be used on aQFuture<T> QtConcurrent::run()
, whatever it does is not a "native thread pause".] -
What kind of pausing do you have in mind?
- Pause execution in the middle of a function call? OR
- Finish processing the current event, and then pause the processing of future events?
The latter should be quite simple to implement yourself. I'm not sure if the former is even possible in C++.
-
@JKSH said in Pausing a QThread:
I'm not sure if the former is even possible in C++
it should be now with Coroutines (C++20) :D
-
@JKSH said in Pausing a QThread:
The latter should be quite simple to implement yourself. I'm not sure if the former is even possible in C++.
?
I'm beginning to see my expectations may have been incorrect....
Windows first. It has (https://docs.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-suspendthread):
DWORD SuspendThread( [in] HANDLE hThread );
allowing one thread to suspend another. However I do now note:
This function is primarily designed for use by debuggers.
Linux next. I assumed there would be e.g. a
pthread_pause
/_resume()
call, but it seems not.For a process, as you know e.g. from a terminal you can type Ctrl+Z to suspend the process. That will send a
SIGSTOP
to the process, and later aSIGCONT
to resume it. If this can be done for processes I thought it could be done for threads....Let's say: I have code to compute the Ackermann function (or similar process-intensive computation) :) I include this in my Qt project, but the author did not write it with a thread in mind and it does not check some state or interruption or pause flag as it goes. I do not want touch its source code.
Now I notice that as it runs it fully occupies a core and my computer is getting hot! Perhaps the user does something in the UI where he might be going to specify a new number to calculate it for, and while waiting for him to enter the new number I want to stop the processor overheating if he is going to cause it to need to restart but we don't know yet, so we want to pause where it is now before either continuing or stopping it.
Surely these OSes have the architecture to e.g. tell the OS scheduler to not longer allocate any time slices to a given thread for a while? Or not??
-
@JonB said in Pausing a QThread:
Surely these OSes have the architecture to e.g. tell the OS scheduler to not longer allocate any time slices to a given thread for a while? Or not??
isn't that what sleep() does ?
-
@J-Hilk said in Pausing a QThread:
it should be now with Coroutines (C++20) :D
If I've understood it correctly, coroutines still need to be written in a way such that the routine pauses itself at well-defined spots?
This is not the same as an external actor suspending a function at any arbitrary spot.
@JonB said in Pausing a QThread:
Let's say: I have code to compute the Ackermann function (or similar process-intensive computation) :) I include this in my Qt project, but the author did not write it with a thread in mind and it does not check some state or interruption or pause flag as it goes. I do not want touch its source code.
Then you file a bug report/feature request and ask the author to touch the source code :-)
Surely these OSes have the architecture to e.g. tell the OS scheduler to not longer allocate any time slices to a given thread for a while? Or not??
I have not seen such a feature. I'd be most interested if someone can find an example.
-
@JKSH said in Pausing a QThread:
Then you file a bug report/feature request and ask the author to touch the source code :-)
Sorry, not fair. When I write a function to do Ackermann function, I just write it to do the steps. I do not go "Maybe someone will want to run this in a thread in the future and would like me to check on each iteration whether to pause or not".
I have not seen such a feature. I'd be most interested if someone can find an example.
That is what e.g. Linux pause(2), sigsuspend(2) or the
SIGSTOP
signal all do. They all suspend a process/thread, it does not get any further time splices from the scheduler till the resumption signal is deleivered? -
@JonB said in Pausing a QThread:
That is what e.g. Linux pause(2), sigsuspend(2) or the SIGSTOP signal all do.
And then again pause() and sigsuspend() only pause the current thread and cannot be used to pause a different thread (which is the actual question). Maybe one can deliver
SIGSTOP
to a different thread? -
@SimonSchroeder said in Pausing a QThread:
And then again pause() and sigsuspend() only pause the current thread and cannot be used to pause a different thread (which is the actual question)
Absolutely. The question (from @JKSH) was what could do this.
Maybe one can deliver SIGSTOP to a different thread?
Absolutely you can. E.g. as I said this (or
SIGTSTP
) is what is happening when you Ctrl+Z etc. from a shell.My point was that the OS thread/process time-slice scheduler can do all of this, so the facilities for "pausing" must be there.
-
The broader argument is that pausing a thread is a misuse of them. Also, you need to consider that the qt thread abstraction may not be a true system level thread, but instead a pseudo-thread that supports the common threading api and behaviour (to some extent).
As for pause/yield/etc as in coroutines...seems like it's a 20 year full circle back to the era of cooperative multi-tasking, when the favored model has clearly become preemptive MT.
Seems to me that the hint about how qt threads exist would be whether
std::this_thread::sleep_for() works as expected, or does it introduce side-effects?