#include <IceUtil/Thread.h>
#include <IceUtil/Mutex.h>
class DataObj {
public:
DataObj() : _val(0) {}
int getValue() {
// _m.lock();
// _val++;
// _m.unlock();
IceUtil::Mutex::Lock lock(_m); // RAII
_val++;
return _val;
}
private:
int _val;
IceUtil::Mutex _m;
};
class MyThread : public IceUtil::Thread {
public:
MyThread(DataObj *obj) : _obj(obj) {}
virtual void run() {
IceUtil::ThreadControl self;
while (1)
{
int v = _obj->getValue();
if ( v > 20 )
break;
printf("#%d, v = %d\n", self.id(), v);
}
}
private:
DataObj *_obj;
};
int main(int argc, char *argv[])
{
IceUtil::ThreadPtr p1, p2;
IceUtil::ThreadControl c1, c2;
DataObj *obj = new DataObj;
p1 = new MyThread(obj);
p2 = new MyThread(obj);
c1 = p1->start();
c2 = p2->start();
c1.join();
c2.join();
delete obj;
printf("exit!\n");
return 0;
}
------------------------------------------------------------------
D:\sandbox\ice\thread\Debug>mutex.exe
#17192, v = 1
#18400, v = 2
#17192, v = 3
#18400, v = 4
#17192, v = 5
#18400, v = 6
#17192, v = 7
#18400, v = 8
#17192, v = 9
#18400, v = 10
#17192, v = 11
#18400, v = 12
#17192, v = 13
#18400, v = 14
#17192, v = 15
#18400, v = 16
#17192, v = 17
#18400, v = 18
#17192, v = 19
#18400, v = 20
exit!
------------------------------------------------------------------
Monitor
主要用于 suspend a thread inside a critical region and have that thread wake up again at a later time。
其实就是 mutex + condition 的封装而已。IceUtil::Monitor 在调用 notify() 之后,会等到 mutex 真正 unlock 后,才会唤醒其他线程(Mesa monitor semantics)。
-------------------------- monitor.cpp --------------------------
#include <IceUtil/Monitor.h>
#include <IceUtil/Mutex.h>
#include <IceUtil/Thread.h>
#include <list>
#include <stdio.h>
template <typename T>
class Queue {
public:
typedef IceUtil::Monitor<IceUtil::Mutex> QueueMonitor;
public:
void put(const T &item) {
QueueMonitor::Lock lock(_monitor);
_list.push_back(item);
if (_list.size() == 1)
_monitor.notify();
}
T get() {
QueueMonitor::Lock lock(_monitor);
while (_list.size() == 0)
_monitor.wait();
T item = _list.front();
_list.pop_front();
return item;
}
private:
std::list<T> _list;
QueueMonitor _monitor;
};
Queue<int> int_queue;
class Producer : public IceUtil::Thread {
public:
virtual void run() {
for ( int i = 0; i < 10; i++ )
int_queue.put(i);
}
};
class Consumer : public IceUtil::Thread {
public:
virtual void run() {
int val = int_queue.get();
IceUtil::ThreadControl self;
printf("#%d, v = %d\n", self.id(), val);
}
};
int main(int argc, char *argv[])
{
IceUtil::ThreadPtr p1, p2, p3;
IceUtil::ThreadControl c1, c2, c3;
p1 = new Producer;
c1 = p1->start();
p2 = new Consumer;
p3 = new Consumer;
c2 = p2->start();
c3 = p3->start();
c1.join();
c2.join();
c3.join();
printf("exit!\n");
return 0;
}
------------------------------------------------------------------
D:\sandbox\ice\thread\Debug>monitor.exe
#10032, v = 0
#10024, v = 1
exit!
------------------------------------------------------------------
Ice 对 thread 相关内容的封装,还是很简洁、实用的。:-)
评论