semaphores are pretty simple, basically they have an internal counter which you give an initial value. you can think of this value as the number of threads which can pass into a protected block of code (so a 1 would mean 1 at a time, 2 means 2 can go int, etc).
every time a thread does a "p" (also known as "wait" or "down") the count is decremented, if it becomes less than 0, the calling thread is blocked and put on the semaphores wait list.
every time a thread does a "v" (also known as a "signal" or "up") the count is incremented, if it becomes less than or equal to 0, then a random thread is selected from this semaphores wait list and woken up.
both p and v operations must be atomic (non-divisable) for proper operation. on a uniprocessors system, simply disabling interrupts will do.
here is some example code: (BTW: autolock is a class i use for makeing a function atomic system wide).
Code: Select all
void Semaphore::p() {
// this is to ensure atomic operation
AutoLock _(SysLock::instance());
--m_Value;
if(m_Value < 0) {
block();
}
}
void Semaphore::v() {
// this is to ensure atomic operation
AutoLock _(SysLock::instance());
++m_Value;
if(m_Value <= 0) {
unblock();
}
}
so suppose you had a section of code, that only 1 thread must be able to run at a time..
you could do this:
Code: Select all
// all threads must share this instance of the variable
// make it a static one for example's sake
static Semaphore mutex(1);
mutex.p();
// do critical section
mutex.v();
hope that clears some things up for ya, and good luck.
proxy