| Trolltech Home | Qt-interest Home | Recent Threads | All Threads | Author | Date | |
| All threads index page 2 | |
Is there a Qt equivalent to the Win32 function call "SuspendThread()" I allow the use to suspend a calculation thread for an arbitrary length of time in the Win32 version of ArgusLab; am interested in doing likewise in Qt. Mark -- [ signature omitted ]
Oops, almost forgot: I'm interested in SuspendThread and ResumeThread() behavior. Any pointers would be great! I've culled all the usual sources of Qt help info before posting this; don't know if it can be done? Mark Mark Thompson wrote: > > Is there a Qt equivalent to the Win32 function call "SuspendThread()" > > I allow the use to suspend a calculation thread for an arbitrary > length of time in the Win32 version of ArgusLab; am interested in > doing likewise in Qt. > > Mark > > -- [ signature omitted ]
Mark Thompson wrote:
> Oops, almost forgot: I'm interested in SuspendThread and
> ResumeThread() behavior.
>
> Any pointers would be great! I've culled all the usual sources of Qt
> help info before posting this; don't know if it can be done?
I do not think that you can replicate the original behaviour (in a
cross-platform manner)
What you could do is create a QThread subclass:
(Pseudo-code, compile on your own risk ;-)
=======
class SuspendableThread : public QThread
{
Q_OBJECT
public:
[...]
public Q_SLOTS:
void suspend();
void resume();
public:
static void suspendPoint();
private:
QMutex suspendMutex;
int suspendCount;
QWaitCondition suspendCondition;
};
void SuspendableThread::suspend()
{
QMutexLocker lock(&suspendMutex);
++suspend;
}
void SuspendableThread::resume()
{
QMutexLocker lock(&suspendMutex);
--suspend;
if (suspendCout == 0)
suspendCondition.wakeAll();
}
void SuspendableThread::suspendPoint()
{
SuspendableThread *thread =
qobject_cast<SuspendableThread *>(QThread::currentThread());
if (!thread) {
qWarning("SuspendableThread::suspendPoint "
"called from a non suspendable Thread!");
return;
}
thread->suspendMutex.lock();
while(suspendCount > 0)
thread->suspendCondition.wait(&(thread->suspendMutex));
thread->suspendMutex.unlock();
}
=====
I think this might do something akin to what you like to achieve? One
ceveat is that you would have to sprinkle your code with
SuspendableThread::suspendPoint() calls, and it is probably not the
most performant implementation neither. But, on the other hand, you can
avoid suspending a thread that holds a Mutex...
Hope that helps :-)
Have a nice day
- Jan Krämer
--
[ signature omitted ]
Hi, > I allow the use to suspend a calculation thread for an arbitrary length > of time in the Win32 version of ArgusLab; am interested in doing > likewise in Qt. If you want to suspend the thread from within the thread itself, try QThread::sleep(). If you want to suspend the thread from another thread, I don't think there's anything exactly equivalent to SuspendThread(). We might help writing code with equivalent behavior if you explain the general context and why you need to suspend the thread. -- [ signature omitted ]
Hi Dimitry, Thanks for the response. The ArgusLab application is a molecular modeling program (current release is written in Win32). Users may run several calculations on molecular systems at the same time. Currently, users can suspend a calculation in order to examine the current state as displayed in the graphics window. Also, for teaching purposes, it is very handy to be able to pause and resume calculations to show students intermediate results. One option is for me to simply use the Win32 method (if I can get the handle of the Windows thread from the QThread object). This would reduce my cross-platform capability for the immediate future. However, my main interest in Qt is as a C++ framework for Windows. I had no immediate plans to support Mac or Linux in the initial Qt releases of ArgusLab. Regards, Mark Dimitri wrote: > Hi, > >> I allow the use to suspend a calculation thread for an arbitrary >> length of time in the Win32 version of ArgusLab; am interested in >> doing likewise in Qt. > > If you want to suspend the thread from within the thread itself, try > QThread::sleep(). > > If you want to suspend the thread from another thread, I don't think > there's anything exactly equivalent to SuspendThread(). We might help > writing code with equivalent behavior if you explain the general > context and why you need to suspend the thread. > > -- > Dimitri > > -- > To unsubscribe - send a mail to qt-interest-request@xxxxxxxxxxxxx with > "unsubscribe" in the subject or the body. > List archive and information: http://lists.trolltech.com/qt-interest/ > > > > -- [ signature omitted ]
Hi,
> The ArgusLab application is a molecular modeling program (current
> release is written in Win32). Users may run several calculations on
> molecular systems at the same time. Currently, users can suspend a
> calculation in order to examine the current state as displayed in the
> graphics window. Also, for teaching purposes, it is very handy to be
> able to pause and resume calculations to show students intermediate
> results.
Pausing and resuming calculations should be handled within the
calculation thread itself, by testing the value of a boolean wherever
needed, for example:
void Calculation::run() {
for (int i= 0; i < iterations; ++i) {
while (freeze)
sleep();
small_piece_of_calculation();
while (freeze)
sleep();
another_small_piece_of_calculation();
}
}
You shouldn't be using SuspendThread() for that: calculations may be
suspended while updating the state of the calculation, leaving it in a
corrupted or intermediate state that doesn't make sense to the user.
--
[ signature omitted ]
Dimitri wrote:
> Hi,
>
>> The ArgusLab application is a molecular modeling program (current
>> release is written in Win32). Users may run several calculations on
>> molecular systems at the same time. Currently, users can suspend a
>> calculation in order to examine the current state as displayed in the
>> graphics window. Also, for teaching purposes, it is very handy to be
>> able to pause and resume calculations to show students intermediate
>> results.
>
> Pausing and resuming calculations should be handled within the
> calculation thread itself, by testing the value of a boolean wherever
> needed, for example:
>
> void Calculation::run() {
> for (int i= 0; i < iterations; ++i) {
> while (freeze)
> sleep();
> small_piece_of_calculation();
> while (freeze)
> sleep();
> another_small_piece_of_calculation();
> }
> }
>
> You shouldn't be using SuspendThread() for that: calculations may be
> suspended while updating the state of the calculation, leaving it in a
> corrupted or intermediate state that doesn't make sense to the user.
>
Thanks for the interesting suggestion!
Your suggestion is terrific, but it won't work for our system. First,
there is no corruption of anything during a SuspendThread/ResumeThread
set of method calls. What you see is what you get (aside from some IO
buffers perhaps not being flushed for the last couple of writes to the
output file). Also, the molecule on the graphics screen is safe to
SuspendThread since we lock all critical UI objects (e.g. the user
cannot edit a molecule during a calculation).
Breaking up the code into small chunks and sprinkling it with
"while(freeze)" would work great for threads performing small tasks.
However, for our compute engines (which consist of hundreds of thousands
of lines of mature debugged code) it would be highly invasive and
destabilizing to chunk up the code in this manner.
Cheers,
Mark
> --
> Dimitri
>
> --
> To unsubscribe - send a mail to qt-interest-request@xxxxxxxxxxxxx with
> "unsubscribe" in the subject or the body.
> List archive and information: http://lists.trolltech.com/qt-interest/
>
>
>
>
--
[ signature omitted ]
Hi, > Your suggestion is terrific, but it won't work for our system. First, > there is no corruption of anything during a SuspendThread/ResumeThread > set of method calls. What you see is what you get (aside from some IO > buffers perhaps not being flushed for the last couple of writes to the > output file). Also, the molecule on the graphics screen is safe to > SuspendThread since we lock all critical UI objects (e.g. the user > cannot edit a molecule during a calculation). I don't understand what you mean by "what you see is what you get". If a structure or array is being updated while you suspend the thread, it will be left in an intermediate or incoherent state - maybe the word "corrupted" was not well chosen in this context - but I do understand that it might not be a problem when performing a calculation which consists of iterations on an array. Also I'm not sure how the UI object lock and SuspendThread() are connected, but that's probably because I don't know enough about SuspendThread(), I'll have a look at the MSDN page. > Breaking up the code into small chunks and sprinkling it with > "while(freeze)" would work great for threads performing small tasks. > However, for our compute engines (which consist of hundreds of thousands > of lines of mature debugged code) it would be highly invasive and > destabilizing to chunk up the code in this manner. As far as I know this is how it's usually done for compute engines. Suspending might be OK but abruptly terminating threads is not a good idea. So you have to test for a boolean somewhere to be able to stop a calculation. Well, it is possible to terminate a thread to stop the calculation it runs, but the application may be left in a corrupted state. It's much better to run a separate process since process termination will clean up everything except maybe shared memory and similar inter-process resources. -- [ signature omitted ]
Hi Dimitri, My mistake...sorry! Yes, you are certainly correct, that a suspended thread may leave critical fields in objects and data structures in an indeterminate state. Our use has been for users to "see" the current graphics interpretation of the calculation on the screen, and to also allow for examining the calculation output file. In the end, it's not a critical feature in the program, and is perhaps best to consider leaving it out for the future. The intention of suspending the thread is not to kill the calculation, which would indeed result in the resource corruption you mention. Rather, suspend and resume are used to temporarily stop a calculation to examine it's current state (as viewed on the screen and as produced in the latest flush of output buffers to the output file), and then to resume the calculation. Killing the calculation is another can of worms! There are two types of compute engines run in ArgusLab: 1. Those we have written and which run either as COM objects or are compiled into the main executable. 2. 3rd party programs (like Gaussian; a popular commercial computational chemistry program). Case #2: We currently run these in a separate process and "wrap" monitoring the state of the output file for intermediate results that are turned into updates rendered on the graphics screen. Pausing, resuming, and killing these types of calculations is pretty straightforward, since when we kill the calc, the external process simply goes away and we don't carry around any un-reclaimed resources in the main ArgusLab process. Case #1: Killing these calculation threads has been a problem. In the past, we adopted something similar to your suggestion of sprinkling the code with "while (freeze)" type statements, where the calculation thread checks for requests to die gracefully (and allow freeing up resources). This proved to be quite a headache for some of our compute engines and we are not happy with the current status of using that approach and extending it to check for pausing & resuming threads. Thanks, Mark Dimitri wrote: > Hi, > >> Your suggestion is terrific, but it won't work for our system. >> First, there is no corruption of anything during a >> SuspendThread/ResumeThread set of method calls. What you see is what >> you get (aside from some IO buffers perhaps not being flushed for the >> last couple of writes to the output file). Also, the molecule on the >> graphics screen is safe to SuspendThread since we lock all critical >> UI objects (e.g. the user cannot edit a molecule during a calculation). > > I don't understand what you mean by "what you see is what you get". If > a structure or array is being updated while you suspend the thread, it > will be left in an intermediate or incoherent state - maybe the word > "corrupted" was not well chosen in this context - but I do understand > that it might not be a problem when performing a calculation which > consists of iterations on an array. Also I'm not sure how the UI > object lock and SuspendThread() are connected, but that's probably > because I don't know enough about SuspendThread(), I'll have a look at > the MSDN page. > >> Breaking up the code into small chunks and sprinkling it with >> "while(freeze)" would work great for threads performing small tasks. >> However, for our compute engines (which consist of hundreds of >> thousands of lines of mature debugged code) it would be highly >> invasive and destabilizing to chunk up the code in this manner. > > As far as I know this is how it's usually done for compute engines. > Suspending might be OK but abruptly terminating threads is not a good > idea. So you have to test for a boolean somewhere to be able to stop a > calculation. Well, it is possible to terminate a thread to stop the > calculation it runs, but the application may be left in a corrupted > state. It's much better to run a separate process since process > termination will clean up everything except maybe shared memory and > similar inter-process resources. > > -- > Dimitri > > -- > To unsubscribe - send a mail to qt-interest-request@xxxxxxxxxxxxx with > "unsubscribe" in the subject or the body. > List archive and information: http://lists.trolltech.com/qt-interest/ > > > > -- [ signature omitted ]
Hi, > Case #1: Killing these calculation threads has been a problem. In the > past, we adopted something similar to your suggestion of sprinkling the > code with "while (freeze)" type statements, where the calculation thread > checks for requests to die gracefully (and allow freeing up resources). > This proved to be quite a headache for some of our compute engines and > we are not happy with the current status of using that approach and > extending it to check for pausing & resuming threads. Yes, threads cannot do everything a process does, such as cleaning up memory (since memory is shared by all the threads of a process). You certainly do seem to know what you're doing, but I have seen other users think that threads will auto-magically solve problems such as integrating long calculations (thus unable to react to events) into an event-driven programs. Unfortunately, unless code is sprinkled with if's or while's, it's not possible to stop or suspend a calculation running in a thread in a consistent state, because you don't control where the code is interrupted and you can't clean up after interrupting. That may be acceptable in some cases, especially when you know what you're doing. I just wanted to point out that threads are not silver bullets when it comes to integrating long calculations in an event-driven program. External processes are a cleaner solution, although more involved because of Inter-Process Communication. Threads may help when it's not an option to modify the original (not designed for event-driven environments) source code and you don't have time to code IPC. In that case threads may provide a quick'n'dirty solution, but you need to be aware of the caveats and limitations. Threads are very popular these days (partly because of multi-core processors) but do consider external processes (they'll also work with multi-core processors) before going for threads when integrating long calculations into event-driven programs - when it's feasible given your constraints. -- [ signature omitted ]
Hi Mark,
In my app, I :
- connect a suspendThread() signal emited from the GUI to a
onSuspendThread() slot in my thread (asyncrounous connection)
- connect a resumeThread() signal emited from the GUI to a onResumeThread()
slot in my thread (asyncrounous connection)
- set up an event loop in my QThread by calling exec()
- set up a 0 ms timer in the thread while it is running.
Something like (pseudo code)
class MyThreadObject {
QTimer myTimer;
MyThreadObject() {
connect( &myTimer, timeout(), this, onTimeOut());
}
slot onSuspendThread() {
myTimer.stop();
}
slot onResumeThread() {
myTimer.start(0);
}
private slot onTimeOut() {
// do a few comutation steps.
// Should return "quickly" to the event loop
}
}
class MyThread {
slot MyThread:run() {
MyThreadObject threadObject; //=> the threadObject affinity is the thread
// here, connect the appropriate signals to the appropriate slots
threadObject.onResumeThread();
exec();
}
}
When suspended, the event loop is still active... But this is not costly.
Best-
Nicolas
Mark Thompson wrote:
>
> Is there a Qt equivalent to the Win32 function call "SuspendThread()"
>
> I allow the use to suspend a calculation thread for an arbitrary length
> of time in the Win32 version of ArgusLab; am interested in doing
> likewise in Qt.
>
> Mark
>
>
--
[ signature omitted ]
Nicolas Castagne wrote:
Oups,
of course MyThread in the previous pseudo code extends QThread :
> class MyThread : public QThread {
> slot MyThread:run() {
> MyThreadObject threadObject; //=> the threadObject affinity is the
> thread // here, connect the appropriate signals to the appropriate
> slots
>
> threadObject.onResumeThread();
> exec();
> }
Best-
--
[ signature omitted ]
Hi Nicolas,
Thanks! I will study this idea.
Mark
Nicolas Castagne wrote:
> Nicolas Castagne wrote:
>
> Oups,
> of course MyThread in the previous pseudo code extends QThread :
>
>> class MyThread : public QThread {
>> slot MyThread:run() {
>> MyThreadObject threadObject; //=> the threadObject affinity is the
>> thread // here, connect the appropriate signals to the appropriate
>> slots
>>
>> threadObject.onResumeThread();
>> exec();
>> }
>>
>
> Best-
>
> --
> To unsubscribe - send a mail to qt-interest-request@xxxxxxxxxxxxx with "unsubscribe" in the subject or the body.
> List archive and information: http://lists.trolltech.com/qt-interest/
>
>
>
>
>
--
[ signature omitted ]
Am Sonntag, 14. Januar 2007 06:59 schrieb Mark Thompson: > Is there a Qt equivalent to the Win32 function call "SuspendThread()" > > I allow the use to suspend a calculation thread for an arbitrary length > of time in the Win32 version of ArgusLab; am interested in doing > likewise in Qt. If you only need to support win32, why don't you simply call SuspendThread()/ResumeThread() with the handle returned by currentThreadId(). Your thread-class could provide these 2 methods by having an internal thread-id (let's call it m_threadID) which is initialized within run() with the value of currentThreadId(). Now in suspendThread() you call SuspendThread( m_threadID ) and vice versa. Of course you make your application platform-dependend but at least it would be a solution for win32... toby
Attachment:
Attachment:
pgpAGp6okwBDK.pgp
Description: PGP signature
Message 15 in thread
Hi Toby,
Yep, that is a good suggestion. So far the only Win32-specific code I
have left in the application is the use of COM for accessing compute
engines (these could be made platform independent later).
I will look into this.
Mark
Tobias Doerffel wrote:
> Am Sonntag, 14. Januar 2007 06:59 schrieb Mark Thompson:
>
>> Is there a Qt equivalent to the Win32 function call "SuspendThread()"
>>
>> I allow the use to suspend a calculation thread for an arbitrary length
>> of time in the Win32 version of ArgusLab; am interested in doing
>> likewise in Qt.
>>
> If you only need to support win32, why don't you simply call
> SuspendThread()/ResumeThread() with the handle returned by currentThreadId().
> Your thread-class could provide these 2 methods by having an internal
> thread-id (let's call it m_threadID) which is initialized within run() with
> the value of currentThreadId(). Now in suspendThread() you call
> SuspendThread( m_threadID ) and vice versa. Of course you make your
> application platform-dependend but at least it would be a solution for
> win32...
>
> toby
>
--
[ signature omitted ]