wxWidgets: wxThreadHelper Class Reference

| Version: 3.0.5

Public Member Functions | List of all members
wxThreadHelper Class Referenceabstract
Class List by Category » Threading

`#include </home/Hamis/wxwidgets/wxWidgets3.0/wxWidgets3.0-3.0.5.1-2.x86_64/src/wxWidgets-3.0.5.1/interface/wx/thread.h>`

## Detailed Description

The wxThreadHelper class is a mix-in class that manages a single background thread, either detached or joinable (see wxThread for the differences).

By deriving from wxThreadHelper, a class can implement the thread code in its own wxThreadHelper::Entry() method and easily share data and synchronization objects between the main thread and the worker thread.

Doing this prevents the awkward passing of pointers that is needed when the original object in the main thread needs to synchronize with its worker thread in its own wxThread derived object.

For example, wxFrame may need to make some calculations in a background thread and then display the results of those calculations in the main window.

Ordinarily, a wxThread derived object would be created with the calculation code implemented in wxThread::Entry. To access the inputs to the calculation, the frame object would often need to pass a pointer to itself to the thread object. Similarly, the frame object would hold a pointer to the thread object.

Shared data and synchronization objects could be stored in either object though the object without the data would have to access the data through a pointer. However with wxThreadHelper the frame object and the thread object are treated as the same object. Shared data and synchronization variables are stored in the single object, eliminating a layer of indirection and the associated pointers.

Example:

wxDECLARE_EVENT(myEVT_THREAD_UPDATE, wxThreadEvent);
class MyFrame : public wxFrame, public wxThreadHelper
{
public:
MyFrame(...) { ... }
~MyFrame()
{
// it's better to do any thread cleanup in the OnClose()
// event handler, rather than in the destructor.
// This is because the event loop for a top-level window is not
// active anymore when its destructor is called and if the thread
// sends events when ending, they won't be processed unless
// you ended the thread from OnClose.
// See @ref overview_windowdeletion for more info.
}
...
void DoStartALongTask();
void OnThreadUpdate(wxThreadEvent& evt);
void OnClose(wxCloseEvent& evt);
...
protected:
virtual wxThread::ExitCode Entry();
// the output data of the Entry() routine:
char m_data[1024];
wxCriticalSection m_dataCS; // protects field above
wxDECLARE_EVENT_TABLE();
};
wxDEFINE_EVENT(myEVT_THREAD_UPDATE, wxThreadEvent)
wxBEGIN_EVENT_TABLE(MyFrame, wxFrame)
EVT_THREAD(wxID_ANY, myEVT_THREAD_UPDATE, MyFrame::OnThreadUpdate)
EVT_CLOSE(MyFrame::OnClose)
wxEND_EVENT_TABLE()
void MyFrame::DoStartALongTask()
{
// we want to start a long task, but we don't want our GUI to block
// while it's executed, so we use a thread to do it.
if (CreateThread(wxTHREAD_JOINABLE) != wxTHREAD_NO_ERROR)
{
wxLogError("Could not create the worker thread!");
return;
}
// go!
if (GetThread()->Run() != wxTHREAD_NO_ERROR)
{
wxLogError("Could not run the worker thread!");
return;
}
}
wxThread::ExitCode MyFrame::Entry()
{
// IMPORTANT:
// this function gets executed in the secondary thread context!
int offset = 0;
// here we do our long task, periodically calling TestDestroy():
while (!GetThread()->TestDestroy())
{
// since this Entry() is implemented in MyFrame context we don't
// need any pointer to access the m_data, m_processedData, m_dataCS
// variables... very nice!
// this is an example of the generic structure of a download thread:
char buffer[1024];
download_chunk(buffer, 1024); // this takes time...
{
// ensure no one reads m_data while we write it
wxCriticalSectionLocker lock(m_dataCS);
memcpy(m_data+offset, buffer, 1024);
offset += 1024;
}
// VERY IMPORTANT: do not call any GUI function inside this
// function; rather use wxQueueEvent():
wxQueueEvent(this, new wxThreadEvent(wxEVT_COMMAND_MYTHREAD_UPDATE));
// we used pointer 'this' assuming it's safe; see OnClose()
}
// TestDestroy() returned true (which means the main thread asked us
// to terminate as soon as possible) or we ended the long task...
return (wxThread::ExitCode)0;
}
void MyFrame::OnClose(wxCloseEvent&)
{
// important: before terminating, we _must_ wait for our joinable
// thread to end, if it's running; in fact it uses variables of this
// instance and posts events to *this event handler
if (GetThread() && // DoStartALongTask() may have not been called
GetThread()->IsRunning())
GetThread()->Wait();
Destroy();
}
void MyFrame::OnThreadUpdate(wxThreadEvent& evt)
{
// ...do something... e.g. m_pGauge->Pulse();
// read some parts of m_data just for fun:
wxCriticalSectionLocker lock(m_dataCS);
wxPrintf("%c", m_data[100]);
}
wxCloseEvent
This event class contains information about window and session close events.
Definition: event.h:4048
wxCriticalSection
A critical section object is used for exactly the same purpose as a wxMutex.
Definition: thread.h:583
wxCriticalSectionLocker
This is a small helper class to be used with wxCriticalSection objects.
Definition: thread.h:259
wxFrame
A frame is a window whose size and position can (usually) be changed by the user.
Definition: frame.h:153
wxThreadEvent
This class adds some simple functionality to wxEvent to facilitate inter-thread communication.
Definition: event.h:3357
wxThreadHelper
The wxThreadHelper class is a mix-in class that manages a single background thread,...
Definition: thread.h:429
wxThreadHelper::CreateThread
wxThreadError CreateThread(wxThreadKind kind=wxTHREAD_JOINABLE, unsigned int stackSize=0)
Creates a new thread of the given kind.
wxThreadHelper::GetThread
wxThread * GetThread() const
This is a public function that returns the wxThread object associated with the thread.
wxThreadHelper::Entry
virtual ExitCode Entry()=0
This is the entry point of the thread.
wxThread::Wait
ExitCode Wait(wxThreadWait flags=wxTHREAD_WAIT_BLOCK)
Waits for a joinable thread to terminate and returns the value the thread returned from Entry() or "(...
wxThread::ExitCode
void * ExitCode
The return type for the thread functions.
Definition: thread.h:997
wxID_ANY
@ wxID_ANY
Any id: means that we don't care about the id, whether when installing an event handler or when creat...
Definition: defs.h:596
wxDEFINE_EVENT
#define wxDEFINE_EVENT(name, cls)
Define a new event type associated with the specified event class.
Definition: event.h:4462
wxEND_EVENT_TABLE
#define wxEND_EVENT_TABLE()
Use this macro in a source file to end listing static event handlers for a specific class.
Definition: event.h:4598
wxBEGIN_EVENT_TABLE
#define wxBEGIN_EVENT_TABLE(theClass, baseClass)
Use this macro in a source file to start listing static event handlers for a specific class.
Definition: event.h:4588
wxDECLARE_EVENT
#define wxDECLARE_EVENT(name, cls)
Declares a custom event type.
Definition: event.h:4483
wxDECLARE_EVENT_TABLE
#define wxDECLARE_EVENT_TABLE()
Use this macro inside a class declaration to declare a static event table for that class.
Definition: event.h:4578
wxQueueEvent
void wxQueueEvent(wxEvtHandler *dest, wxEvent *event)
Queue an event for processing on the given object.
wxLogError
void wxLogError(const char *formatString,...)
The functions to use for error messages, i.e.
wxTHREAD_JOINABLE
@ wxTHREAD_JOINABLE
Joinable thread.
Definition: thread.h:675
wxTHREAD_NO_ERROR
@ wxTHREAD_NO_ERROR
No error.
Definition: thread.h:684

##

Library: wxBase

<>< =''>:</>&;&;< =''>\ </></>

See also
  wxThread, wxThreadEvent

## Public Member Functions
| wxThreadHelper (wxThreadKind kind=wxTHREAD_JOINABLE)
| This constructor simply initializes internal member variables and tells wxThreadHelper which type the thread internally managed should be. More...
virtual | ~wxThreadHelper ()
| The destructor frees the resources associated with the thread, forcing it to terminate (it uses wxThread::Kill function). More...
virtual ExitCode | Entry ()=0
| This is the entry point of the thread. More...
virtual void | OnDelete ()
| Callback called by Delete() before actually deleting the thread. More...
virtual void | OnKill ()
| Callback called by Kill() before actually killing the thread. More...
wxThreadError | Create (unsigned int stackSize=0)
wxThreadError | CreateThread (wxThreadKind kind=wxTHREAD_JOINABLE, unsigned int stackSize=0)
| Creates a new thread of the given kind. More...
wxThread * | GetThread () const
| This is a public function that returns the wxThread object associated with the thread. More...
wxThreadKind | GetThreadKind () const
| Returns the last type of thread given to the CreateThread() function or to the constructor. More...

## Constructor & Destructor Documentation

## ◆ wxThreadHelper()

wxThreadHelper::wxThreadHelper | ( | wxThreadKind | kind = `wxTHREAD_JOINABLE` | ) |

This constructor simply initializes internal member variables and tells wxThreadHelper which type the thread internally managed should be.

## ◆ ~wxThreadHelper()

virtual wxThreadHelper::~wxThreadHelper | ( |  | ) |
| virtual

The destructor frees the resources associated with the thread, forcing it to terminate (it uses wxThread::Kill function).

Because of the wxThread::Kill unsafety, you should always wait (with wxThread::Wait) for joinable threads to end or call wxThread::Delete on detached threads, instead of relying on this destructor for stopping the thread.

## Member Function Documentation

## ◆ Create()

wxThreadError wxThreadHelper::Create | ( | unsigned int | stackSize = `0` | ) |

Deprecated:
  Use CreateThread() instead.

## ◆ CreateThread()

wxThreadError wxThreadHelper::CreateThread | ( | wxThreadKind | kind = `wxTHREAD_JOINABLE`,
|  | unsigned int | stackSize = `0`
| ) |  |

Creates a new thread of the given kind.

The thread object is created in the suspended state, and you should call GetThread()->Run() to start running it.

You may optionally specify the stack size to be allocated to it (ignored on platforms that don't support setting it explicitly, e.g. Unix).

Returns
  One of the wxThreadError enum values.

## ◆ Entry()

virtual ExitCode wxThreadHelper::Entry | ( |  | ) |
| pure virtual

This is the entry point of the thread.

This function is pure virtual and must be implemented by any derived class. The thread execution will start here.

You'll typically want your Entry() to look like:

wxThread::ExitCode Entry()
{
while (!GetThread()->TestDestroy())
{
// ... do some work ...
if (IsWorkCompleted)
break;
if (HappenedStoppingError)
return (wxThread::ExitCode)1; // failure
}
return (wxThread::ExitCode)0; // success
}

The returned value is the thread exit code which is only useful for joinable threads and is the value returned by `"GetThread()->Wait()"`.

This function is called by wxWidgets itself and should never be called directly.

## ◆ GetThread()

wxThread* wxThreadHelper::GetThread | ( |  | ) | const

This is a public function that returns the wxThread object associated with the thread.

## ◆ GetThreadKind()

wxThreadKind wxThreadHelper::GetThreadKind | ( |  | ) | const

Returns the last type of thread given to the CreateThread() function or to the constructor.

## ◆ OnDelete()

virtual void wxThreadHelper::OnDelete | ( |  | ) |
| virtual

Callback called by Delete() before actually deleting the thread.

This function can be overridden by the derived class to perform some specific task when the thread is gracefully destroyed. Notice that it will be executed in the context of the thread that called Delete() and not in this thread's context.

TestDestroy() will be true for the thread before OnDelete() gets executed.

Since
  2.9.2

See also
  OnKill()

## ◆ OnKill()

virtual void wxThreadHelper::OnKill | ( |  | ) |
| virtual

Callback called by Kill() before actually killing the thread.

This function can be overridden by the derived class to perform some specific task when the thread is terminated. Notice that it will be executed in the context of the thread that called Kill() and not in this thread's context.

Since
  2.9.2

See also
  OnDelete()