Re: MT Design Question
"Anthony Williams" <anthony.ajw@gmail.com> wrote in message
news:87hbid14ip.fsf@gmail.com...
"Balog Pal" <pasa@lib.hu> writes:
Doing a poll from this, really IDLE thread is really not good. You
already fiddled with cond+fake mutex, that is a working way. I could
suggest an alternative: use just a mutex.
1. main thread sets variable atomic<int> to N that is the number of
threads (N=3 in your example.
2. create and lock a mutex
3. launch N threads. on exit each decrements the variable, if the
result is zero unlocks the mutex. (They use the cancel signal to each
other too certainly.)
Oops. On must platforms, and definitely with a C++0x std::mutex, it is
undefined behaviour to unlock a mutex from a thread other than that
which locked it. This is the use for a semaphore (which we don't have in
C++0x).
FWIW, you can construct a fairly efficient semaphore with C++0x. For
instance, I will augment Joe Seighs original semaphore algorithm he posted
over on `comp.programming.threads' a while back:
<pseudo-code sketch>
_______________________________________________________________
// basically, a slow `condvar+mutex' based semaphore...
struct waitset
{
unsigned m_count; // = 0
std::condition_variable m_cond;
std::mutex m_mutex;
void signal()
{
m_mutex.lock();
++m_count;
m_mutex.unlock();
m_cond.notify_one();
}
void wait()
{
m_mutex.lock();
while (! m_count) m_cond.wait(m_mutex);
--m_count;
m_mutex.unlock();
}
};
// finally, the actual "fast" semaphore! :^)
struct fsem
{
std::atomic<signed> m_count; // = 0
waitset m_waitset;
void post()
{
if (m_count.fetch_add(1, mb_release) < 0)
m_waitset.signal();
}
void wait()
{
if (m_count.fetch_sub(1, mb_acquire) < 1)
m_waitset.wait();
}
};
_______________________________________________________________
Barring any damn typos, the algorithm itself is pretty darn simple and
straightforward. :^)
Oh yeah, one more thing: You cannot signal this semaphore from a signal
handler!!!
Ouch...