This page is a work in progress.
When multi-threading an application, one should think about the following:
Add the following include files to the header-file for the class:
#include <Poco/Thread.h> #include <Poco/Runnable.h> #include <Poco/Semaphore.h> #include <Poco/Mutex.h>
The device class should publicly inherit the Poco::Runnable class.
The following data members should be added to the class:
Poco::Thread myThread; Poco::Semaphore mySemaphore; bool StopThread;
The class also needs a method run, that performs the work that needs to run in the separate thread:
void <class-name>::run() { try { for(;;) { mySemaphore.wait(); // main thread will set the semaphore // when work needs to be done, or if // the thread needs to terminate. if (StopThread) return; // main thread has signalled us that // we need to terminate. < work >; // do work as long as work needs to be // done. } } catch(...) {} // if an exception occurs, catch it and // terminate. The main thread will see // that this thread has terminated, and // throw a new exception. }
mySemaphore and myThread need to be added to the initializer list on the class constructor:
... , mySemaphore(0,1), myThread("<thread-name>")
The thread is started from the constructor:
StopThread = false; myThread.start(*this);
Whenever there is work that the thread needs to do, the thread is signalled with the following code:
mySemaphore.set();
The thread should be shut down from the class' destructor:
StopThread = true; mySemaphore.set(); // signal the thread to end myThread.join(); // wait for the thread to end
To catch unexpected termination of a thread due to an exception, the status of the thread is checked periodically (from DoClock):
If data structures need to be accessed by multiple threads, it may be necessary to protect these structures by a Mutex. These mutexes are class members of type Poco::Mutex, for instance:
Poco::Mutex myLock;
The access to the data structures is then surrounded by a lock/unlock construction:
myLock::lock(); <access structure>; myLock::unlock();