Here I'd like to share two handy classes with the ones
who would like to use simple ("Java style") multithreading in C++.
You are free to use and modify these sources. Also, any feedback is welcome,
to here.
Source files
Two classes are declared & defined in the files
simplethreading.h
and simplethreading.cpp. I'm using POSIX's
gadgets for this, namely pmutex and pthread,
as they are
a good option if someone considers portability. I've tried this on Linux
and Solaris, but it should work on Windows as well. Please
let me know if you try it. (The include file may need some stuff like
#if defined(WIN32)
#include <...windows specific includes...>
...
#else
#include <...*nix specific includes...>
...
#endif
)
How to use them
Mutex
This class is a quite straightforward implementation
of a 2-state semaphore, called mutex in the programmers'
terminology [standing for mutual exclusion]: it can
be locked or unlocked. When it's locked by thread_1 and thread_2
(or any further thread) wants to lock it, thread_2 is blocked until
thread_1unlocks (releases) the mutex. Then thread_2 gets the execution.
You can just instantiate one as a usual class. After
construction the semaphore is in unlocked state. One more method is provided
for thread_2 to avoid blocking, it is:
bool Mutex::isLocked()
It can be used in situations where the thread wanting to lock the mutex
must know if it can do that without being blocked or not (and in the latter
case it may choose to do something else instead).
SimpleThread
This class is a base class that one should subclass
to implement a separate thread. The basic usage is quite simple: create
a public subclass of SimpleThread, and override its pure virtual
run method:
virtual void run()
This method should do what you want your thread to do. The thread will
end when the run() method has returned. The thread can be started
by calling the
void start()
method.
Some more sophisticated usage can be implemented
by using the feature that the base class can store a pointer as user data.
You can pass the user data to the base class (i.e. SimpleThread)
via the member initialization list in the constructor of the derived
class. The subclass can access this later (i.e. in the run() method)
from the inherited member variable
void *userData
Typically, this should be a pointer to a data structure or class that the
thread should operate on. The subclass should typecast it from void
* to the wanted type, of course.
The class has a stop() method as well, which
waits for the thread to finish. Note that this does not immediately
stop the thread. If you need that, you can either:
introduce a new method or change stop() to use the function pthread_kill
instead, but be warned that this may finish the thread without a graceful
cleanup, i.e. resources held by the thread may not be freed, unless signal
handlers are specified.
or simply implement a "stop" flag which is periodically checked by the
thread and if set, the run() method may just return or execute (in
any method within the thread's context) the pthread_exit call.