Trolltech Home | Qt-interest Home | Recent Threads | All Threads | Author | Date
All threads index page 2

Qt-interest Archive, January 2007
Suspend Thread?


Message 1 in thread

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 ] 

Message 2 in thread

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 ] 

Message 3 in thread

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 ] 

Message 4 in thread

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 ] 

Message 5 in thread

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 ] 

Message 6 in thread

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 ] 

Message 7 in thread

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 ] 

Message 8 in thread

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 ] 

Message 9 in thread

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 ] 

Message 10 in thread

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 ] 

Message 11 in thread

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 ] 

Message 12 in thread

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 ] 

Message 13 in thread

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 ] 

Message 14 in thread

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 ]