#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();
}
}