Threads are both a blessing and a curse.
You can do a lot of good with proper thread management and you can also turn an otherwise simple, beautiful and responsive program into a slow unmanageable mess.
But before we get into all of that lets discuss the basics of multi-threading.
Computers are designed to execute instructions in a sequence, we call a sequence of instructions a program.
CPU's can really only do one thing at a time, even though right now you are reading this, downloading music in the background, and probably chatting on IM. Just like you, your CPU is still really only doing one thing at a time.
Your computer is able to "multi-task", by quickly switching between things that it is doing. Again just like you are, by switching between this webpage and your IM client.
Each program your computer runs is called a "process". If a program needs to do more than one thing at a time, then the program needs to break itself down into seperate smaller processes that can be executed "in parallel".
We call these smaller processes "threads", and they enable the CPU to appear to be doing multiple things at once, within the same application.
A good example of why we need threads is the TCP Chat Client application.
If you compile and run it, you will notice that it doesn't receive data from the network while waiting on user input.
That is not a bug, it is a design consideration. Without threads there is no easy and standardized way to wait on input and listen to the network at the same time. We call this thread-blocking.
But wait! Didn't I just say that we don't have threads yet?
Well that is somewhat true. The fact is that every application consists of at least one thread. This is the thread created at program execution time and it's called the main thread. Assuming we don't split the application down into smaller threads, almost every application can be said to be threaded, at least single-threaded. If we do break the program down into multiple parallel threads we call the application "multi-threaded".
Threads are the true context that the operating system uses to swap instructions and data into and out of memory.
Because thread swapping does have a CPU and memory overhead associated with it, so we want to be sure to use threads sparingly.
The point at which a thread swap occurs is more properly called a "context switch" and it's not generally user configurable.
However you can usually force a context switch by putting your threads to sleep. There is no guarantee that the context switch will occur, but most CPU schedulers will know to do it.
Context switching and Thread swapping are only important because of the fact that they have huge repercussions for interactivity in your application. If your app is being a CPU hog, the whole system but especially your app, will feel slow and unresponsive, this makes for a less than pleasing end user experience (EUE).
Threading can get incredibly complex, with mutexes, semaphores and a whole host of other concepts.
For our simple usage of threads we won't be bothering with most of that other than mutexes which simply prevent one thread from messing with data that another thread is using at the moment.
Our Platinum::Thread library will wrap Unix pThreads and Windows WIN32 Threading API, in an easy to use intuitive API.
We wont be implementing a whole host of functions, mostly just.
Platinum::Thread::Create
Platinum::Thread::WaitForFinish
Platinum::Thread::Kill
Platinum::Thread::Yield
Platinum::Thread::Mutex.Lock
Platinum::Thread::Mutex.Unlock
With that said, lets move on to our very first multi-threaded application.