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;
}