#include <vector>
#include <list>
#include <IceUtil/Thread.h>
#include <IceUtil/Monitor.h>
using namespace std;
template<class T> class Queue: public IceUtil::Monitor<IceUtil::Mutex>
{
public:
Queue() : _waitingReaders(0) {}
void put(const T & item)
{
IceUtil::Monitor<IceUtil::Mutex>::Lock lock(*this);
_q.push_back(item);
if (_waitingReaders) notify();
}
T get()
{
IceUtil::Monitor<IceUtil::Mutex>::Lock lock(*this);
while (_q.size() == 0)
{
try
{
++_waitingReaders;
wait();
--_waitingReaders;
} catch (...)
{
--_waitingReaders;
throw;
}
}
T item = _q.front();
_q.pop_front();
return item;
}
private:
list<T> _q;
short _waitingReaders;
};
Queue<int> q;
class ReaderThread : public IceUtil::Thread
{
virtual void run()
{
for (int i = 0; i < 100; ++i)cout << q.get() << endl;
}
};
class WriterThread : public IceUtil::Thread
{
virtual void run()
{
for (int i = 0; i < 100; ++i) q.put(i);
}
};
void main()
{
vector<IceUtil::ThreadControl> threads;
int i;
// Create five reader threads and start them
//
for (i = 0; i < 5; ++i)
{
IceUtil::ThreadPtr t = new ReaderThread;
threads.push_back(t->start());
}
// Create five writer threads and start them
//
for (i = 0; i < 5; ++i)
{
IceUtil::ThreadPtr t = new WriterThread;
threads.push_back(t->start());
}
// Wait for all threads to finish
//
for (vector<IceUtil::ThreadControl>::iterator p= threads.begin(); p!= threads.end(); ++p)
{
p->join();
}
}