注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

Code@Pig Home

喜欢背着一袋Code傻笑的Pig .. 忧美.欢笑.记忆.忘却 .之. 角落

 
 
 

日志

 
 

[ice] thread/mutex/moniter  

2010-05-29 20:18:57|  分类: net_Ice |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |
ice 对多线程的封装,放在 namespace IceUtil 中。下面一一道来。

Thread
对于 thread,继承 IceUtil::Thread,写个 run() 函数即可。
值得一说的是 thread 对象的生命期,t->start() 之后,首先 inc refcnt,然后 run(),run()  结束,dec refcnt,如果 refcnt == 0 则直接 delete this。所以,切忌,只能使用 ThreadPtr,不要直接使用 Thread *。
ThreadControl 是用来管理 thread 的。
-------------------------- thread.cpp --------------------------
#include <IceUtil/Thread.h>
#include <stdio.h>

class CounterThread : public IceUtil::Thread {
public:
    CounterThread(int val) : _val(val) {}

    virtual void run() {
        IceUtil::ThreadControl self;
        for ( int i = 0 ; i < 10; i++ ) {
            printf("#%d, i = %d, val = %d\n", self.id(), i, _val);
        }
    }

private:
    int _val;
};

int main(int argc, char *argv[])
{
    IceUtil::ThreadPtr p1, p2;
    IceUtil::ThreadControl c1, c2;

    p1 = new CounterThread(1);
    p2 = new CounterThread(2);

    c1 = p1->start();
    c2 = p2->start();

    c1.join();
    c2.join();

    printf("exit!\n");
    return 0;
}
------------------------------------------------------------------
D:\sandbox\ice\thread\Debug>thread.exe
#16956, i = 0, val = 1
#14644, i = 0, val = 2
#16956, i = 1, val = 1
#14644, i = 1, val = 2
#16956, i = 2, val = 1
#14644, i = 2, val = 2
#16956, i = 3, val = 1
#14644, i = 3, val = 2
#16956, i = 4, val = 1
#14644, i = 4, val = 2
#16956, i = 5, val = 1
#14644, i = 5, val = 2
#14644, i = 6, val = 2
#14644, i = 7, val = 2
#16956, i = 6, val = 1
#14644, i = 8, val = 2
#16956, i = 7, val = 1
#14644, i = 9, val = 2
#16956, i = 8, val = 1
#16956, i = 9, val = 1
exit!
------------------------------------------------------------------

Mutex
mutex 也很简单,加/解锁 lock() / unlock(),或者选用 IceUtil::Mutex::Lock lock(_m) 更便利。
还有个 IceUtil::RecMutex,就是 recursive mutex,允许一个线程中多次 lock / unlock。
-------------------------- mutex.cpp --------------------------
#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 相关内容的封装,还是很简洁、实用的。:-)
  评论这张
 
阅读(1160)| 评论(1)
推荐 转载

历史上的今天

在LOFTER的更多文章

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017