Thread / Message Queue Classes
ASThread.cpp
ASThread.h
Methods:
At Thread Exit Handlers:
static bool atexit(atexitThreadFn_t Func, void *UserPtr)
Registers a global handler. Multiple calls to atexit with the same {Func,UserPtr} results in only on registration (the same number of unatexit() calls would then be required).
atexit() can be used to cleanup associated TLS resources; where UserPtr is the TLSKey_t.
static void unatexit(atexitThreadFn_t Func, void *UserPtr)
Unregisters a handler for a particular {Func,UserPtr} pair.
Note: unatexit() is optional as no resources are associated with a registration.
Virtual Methods:
const char* GetClassName()
Example Handler:
void MYAtExit(void*) { MYThread *MyThread; ASThread *Active = GetActiveThread(); MyThread = dynamic_cast<MYThread*>(Active); if (MyThread) MyThread->Bye(); else { printf("End of Non-MYThread: %s\n", MyThread->GetClassName()); } return; }
A thread handler can get access to the current thread exiting by calling GetActiveThread().
The "type" of thread returned by GetActiveThread() can be determined by GetClassName() or by RTTI dynamic_cast() operator.
Example 1:
#include <stdio.h> #include <ASThread.h> class ZooThread : public ASThread { private: char *Animal; char *Speak; protected: int ThreadMain(); public: ZooThread(char *animal, char *speak) { Animal = animal; Speak = speak; return; } }; int ZooThread::ThreadMain() { for (int i=0; i < 5; i++) { printf("The %s goes %s\n",Animal,Speak); Sleep(1000); } return 0; } main(int argc, char *argv[]) { ZooThread Cows("Cow","Moo"); ZooThread Dogs("Dog","Ruff"); Cows.Start(); Dogs.Start(); Cows.Wait(); Dogs.Wait(); printf("All Done\n"); return 0; }
Example 2:
#include <stdio.h> #include <ASThread.h> #ifndef _WIN32 #include <unistd.h> #define Sleep(x) sleep(x/1000) #endif class AnimalThread: public ASThread, public MessageQueue { private: char *Animal; char *Speak; protected: int ThreadMain(); public: AnimalThread(char *animal, char *speak) { Animal = animal; Speak = speak; return; } char *GetName() {return Animal;} }; class ZooThread : public ASThread { private: int SleepTime; AnimalThread *WatchAnimal; protected: int ThreadMain(); public: ZooThread(AnimalThread &watchAnimal, int sleepTime) { WatchAnimal = &watchAnimal; SleepTime = sleepTime; return; } }; int AnimalThread::ThreadMain() { int *SpeakMessage = (int *)Receive(); while (SpeakMessage && *SpeakMessage == 1) { printf("The %s goes %s\n",Animal,Speak); delete SpeakMessage; SpeakMessage = (int *)Receive(); } printf("The %s says bye...\n",Animal); return 0; } int ZooThread::ThreadMain() { int *SpeakMessage; for (int i=0; i < 5; i++) { SpeakMessage = new int; if (SpeakMessage) { *SpeakMessage = 1; printf("Sending to %s\n",WatchAnimal->GetName()); WatchAnimal->Send(SpeakMessage); } Sleep(SleepTime); } SpeakMessage = new int; if (SpeakMessage) { *SpeakMessage = 0; WatchAnimal->Send(SpeakMessage); } return 0; } main(int argc, char *argv[]) { AnimalThread Cow("Cow","Moo"); AnimalThread Dog("Dog","Ruff"); ZooThread CowZoo(Cow,1000); ZooThread DogZoo(Dog,2000); printf("Starting Cow\n"); Cow.Start(); printf("Starting Dog\n"); Dog.Start(); printf("Starting CowZoo\n"); CowZoo.Start(); printf("Starting DogZoo\n"); DogZoo.Start(); Cow.Wait(); Dog.Wait(); printf("All Done\n"); return 0; }