Worker Thread Safety

Multithreaded programming is very useful. You can put a worker thread for the main heavy calculation task, and many other user interface threads for thread control, real-time data analyzing, rendering and so on.

The concerning here is to keep data integrity. When a thread is suspended or ended, you may want to save data to a disk, or send to a data viewer. You cannot do these things when the data are in the updating process.
  1. Begin: If a thread has already begun, do nothing, otherwise, kick off a thread.
  2. End: When ending a thread allows the thread to finish some calculations to keep data integrity, otherwise, hold the action till it is safe to kill.
  3. Suspend: When suspending a thread, proceed it only when ThreadProc reaches a safe region.
  4. Resume: Call this method at any time is safe, no matter it is suspending, running, or even no any thread exists at all.

The class WorkerThread makes it true.

Declare ...

	WorkerThread* m_pThread;
	TargetSystem* m_pSystem;

	m_pThread = new  WorkerThread(m_pSystem);
Call ...

	m_pThread->hasBegun();

	m_pThread->isRunning ();
	m_pThread->hasBegun();

	m_pThread->Suspend ();
	m_pThread->Resume ();	

	ThreadSleep rhs(m_pThread);// Suspend and auto resume if running

	m_pThread->End (); 

Suspend and auto-resume

void CPDEsDlg::OnModelParameters() 
{
	ThreadSleep rhs(m_pThread);
	m_pSystem->ModelParameters();
}

Create an object "rhs" without using it, why? You may have this doubt. Actually, the constructor and its destructor have the job done. They are used to suspend and resume a thread, respectively.
// Pair the Suspend and auto Resume
class ThreadSleep
{
public:
	ThreadSleep(WorkerThread* pThread)
		:m_pThread(pThread)
	{
		requireResume = false;
		if( m_pThread->isRunning () )
		{
			m_pThread->Suspend ();
			requireResume = true;
		}
	};
	virtual ~ThreadSleep()
	{
		if( requireResume)
			m_pThread->Resume ();
	};
private:
	WorkerThread* m_pThread;
	bool requireResume;
};