This document provides a brief description of the EAThread modules and then provides some basic information on using these modules. You will want to consult documentation for individual modules for more detailed information about them.
All code is in C++ and largely follows the EA coding guidelines as of January of 2004. All classes are in the EA::Thread C++ namespace. Thus, the fully qualified name of the Mutex class is EA::Thread::Mutex. Most of the code is plain C++ and doesn't attempt to be very academic with the language. Thus RTTI is not used, template usage is used only in one module (FixedAllocator), exception handling is not used, etc. Unit tests have been set up for most of the functionality and are available with the full package. The headers are heavily commented in Doxygen-savvy format and the source code for the primary modules has been heavily commented as well.
| Module |
Description | Source |
Dependencies |
| Thread |
Implements the creation and
control of individual threads. |
eathread.h/cpp eathread_thread.h/cpp |
EABase |
| Storage |
Implements thread-specific
storage (a.k.a. thread-local storage). This is a mechanism whereby a given
named global variable exists not once globally but exists once per thread.
Each thread gets its own view of the variable. |
eathread_storage.h/cpp |
EABase eathead.h/cpp eathread_mutex.h/cpp* |
| Atomic | Implements atomic operations
on integers and pointers. These are useful for doing thread-safe basic
operations and tests on integers or pointers without the cost of more
expensive synchronization primitives such as mutexes. |
eathread_atomic.h |
EABase |
| Mutex |
Implements traditional mutual
exclusion. Mutexes here encompass critical section functionality (a.k.a.
futex) and traditional cross-process exclusion. |
eathread_mutex.h/cpp |
EABase eathread.h/cpp |
| Futex | Implements a fast mutex. A fast mutex is a mutex which can be faster because it acts entirely within user space within the current process and can possibly have some of its code inlined. | eathread_futex.h/cpp | EABase eathread.h/cpp |
| ReadWriteMutex |
Implements a mutex that allows
multiple concurrent reading threads but only one writing thread. This
is useful for situations where one thread is updating a state but multiple
threads may be reading that state. |
eathread_rwmutex.h/cpp |
EABase eathread.h/cpp eathread_atomic.h eathread_condition.h/cpp |
| Semaphore |
Implements a traditional sempahore.
A semaphore has zero or positive count associated with it; a thread can
'grab' the semaphore if the count is greater than zero and grabbing it
reduces its count by one. When the count is zero, threads must wait until
it is incremented, which can be done arbitrarily. The semaphore is the
primitive upon which all other high level primitives can be constructed. |
eathread_semaphore.h/cpp |
EABase eathread.h/cpp eathread_atomic.h |
| Condition |
Implements a condition variable,
which is a synchronization primitive that supports the producer/consumer
pattern. It is for all practical purposes also known as a "monitor" in
Java and C#. This primitive is particularly useful for implementing efficient
cross thread-messaging systems or worker thread job implementations. |
eathread_condition.h/cpp |
EABase eathread.h/cpp eathread_atomic.h eathread_mutex.h/cpp eathread_semaphore.h/cpp |
| Barrier |
Implements a cyclic barrier
primitive. A barrier is a primitive which coordinates the completion of
work by a predetermined number of threads. A barrier has an integer max
"height" and a current height associated with it. When a thread hits the
barrier, it blocks until the prescribed number of threads hit the barrier,
then all are freed. |
eathread_barrier.h/cpp |
EABase |
| SpinLock |
Implements a traditional spin
lock. A spin lock is a special kind of mutex that "spins" in a loop waiting
to be able to continue instead of blocking like a mutex. A spinlock is
more efficient than a mutex but it generally doesn't work unless operating
on a true multi-processing system. When it does work on a true multi-processing
system it is inefficient. |
eathread_spinlock.h |
EABase eathread.h/cpp eathread_sync.h eathread_atomic.h |
| ReadWriteSpinLock |
Implements a spinlock that
allows multiple readers but only a single writer. Otherwise it is similar
to a basic spin lock with respect to purpose and applicability. |
eathread_rwspinlock.h |
EABase eathread.h/cpp eathread_sync.h eathread_atomic.h |
| ThreadPool |
Implements a "pool" of worker
threads available for work. These are commonly used by server systems
to spawn off client-server tasks. |
eathread_pool.h/cpp |
EABase eathread.h/cpp eathread_thread.h/cpp eathread_condition.h/cpp eathread_atomic.h eathread_list.h |
| Sync |
Implements memory synchronization
primitives known as "fences" or "barriers" (not to be confused with thread
barrier primitives). These primitives are useful on multiprocessing platforms
for synchronizing the various processors' view of memory, which can become
"unsynchronized" in the presence of per-processor caches. |
eathread_sync.h |
EABase |
| shared_ptr_mt shared_array_mt |
These are multithread-safe
equivalents to regular smart pointers such as shared_ptr and shared_array.
See the TL (Template Library) for implementations of the regular versions
of these smart pointers. |
shared_ptr_mt.h shared_array_mt.h |
eathread_atomic.h |
* May not be required, depending on your platform/configuration.
We present some
very basic examples of how to use some of the EAThread modules. These
exemplify the simplest uses of these modules and don't go into more
advanced or complicated uses. There is more functionality in each of
the classes than shown; see the documentation or header files for more
information. For clarity, the examples assume that the code has
specified the using EA::Thread; namespace statement.
How to create a thread.
#include "eathread/eathread_thread.h"
int ThreadFunction(void* pContext){
return 0;
}
Thread thread;
thread.Begin(ThreadFunction);
How to use thread-local storage.
#include "eathread/eathread_storage.h"
ThreadLocalStorage tls;
tls.SetValue("hello");
const char* pString = (const char*)tls.GetValue();
How to create and use an atomic integer.
#include "eathread/eathread_atomic.h"
AtomicInteger i = 5;
i += 7;
--i;
if(i.SetValueConditional(3, 6))
printf("i was 6 and now is 3.");
How to create and use a mutex.
#include "eathread/eathread_mutex.h"
Mutex mutex(NULL, true);
mutex.Lock();
mutex.Unlock();
How to create and use a futex.
#include "eathread/eathread_futex.h"
Futex futex;
futex.Lock();
futex.Unlock();
How to create and use a semaphore.
#include "eathread/eathread_semaphore.h"
Semaphore semaphore(NULL, true);
semaphore.Post();
semaphore.Wait();
How to create and use a condition variable.
#include "eathread/eathread_condition.h"
Condition condition(NULL, true);
Mutex mutex(NULL, true);
condition.Signal();
condition.Wait(&mutex);
How to create and use a spin lock.
#include "eathread/eathread_spinlock.h"
SpinLock spinLock;
spinLock.Lock();
spinLock.Unlock();
How to create and use a shared_ptr_mt.
#include "eathread/shared_ptr_mt.h"
shared_ptr_mt pObject(new SomeClass);
pObject->DoSomething();