设为首页 加入收藏

TOP

C++ 多线程编程总结(四)
2012-11-01 15:44:51 来源: 作者: 【 】 浏览:1316
Tags:  线程 编程 总结

   
    4 Lambda 编程(www.cppentry.com)使用foreach 代替迭代器
   
    很多编程(www.cppentry.com)语言已经内建了foreach,但是c++还没有。所以建议自己在需要遍历容器的地方编写foreach函数。习惯函数式编程(www.cppentry.com)的人应该会非常钟情使用foreach,使用foreach的好处多多少少有些,如:
   
    http://www.cnblogs.com/chsword/archive/2007/09/28/910011.html
   
    但主要是编程(www.cppentry.com)哲学上层面的。
   
    示例:
   
    void user_mgr_t::foreach(boost::function<void (user_t&)> func_){
   
    for (iterator it = m_users.begin(); it != m_users.end() ++it){
   
    func_(it->second);
   
    }
   
    }
   
    比如要实现dump 接口,不需要重写关于迭代器的代码
   
    void user_mgr_t:dump(){
   
    struct lambda {
   
    static void print(user_t& user){
   
    //! print(tostring(user);
   
    }
   
    };
   
    this->foreach(lambda::print);
   
    }
   
    实际上,上面的代码变通的生成了匿名函数,如果是c++ 11 标准的编译器,本可以写的更简洁一些:
   
    this->foreach([](user_t& user) {} );
   
    但是我大部分时间编写的程序都要运行在centos 上,你知道吗它的gcc版本是gcc 4.1.2, 所以大部分时间我都是用变通的方式使用lambda函数。
   
    Lambda 函数结合任务队列实现异步
   
    常见的使用任务队列实现异步的代码如下:
   
    void service_t:async_update_user(long uid){
   
    task_queue->post(boost::bind(&service_t:sync_update_user_impl, this, uid));
   
    }
   
    void service_t:sync_update_user_impl(long uid){
   
    user_t& user = get_user(uid);
   
    user.update()
   
    }
   
    这样做的缺点是,一个接口要响应的写两遍函数,如果一个函数的参数变了,那么另一个参数也要跟着改动。并且代码也不是很美观。使用lambda可以让异步看起来更直观,仿佛就是在接口函数中立刻完成一样。示例代码:
   
    void service_t:async_update_user(long uid){
   
    struct lambda {
   
    static void update_user_impl(service_t* servie, long uid){
   
    user_t& user = servie->get_user(uid);
   
    user.update();
   
    }
   
    };
   
    task_queue->post(boost::bind(&lambda:update_user_impl, this, uid));
   
    }
   
    这样当要改动该接口时,直接在该接口内修改代码,非常直观。
   
    5. 奇技淫巧利用shared_ptr 实现map/reduce
   
    Map/reduce的语义是先将任务划分为多个任务,投递到多个worker中并发执行,其产生的结果经reduce汇总后生成最终的结果。Shared_ptr的语义是什么呢?当最后一个shared_ptr析构时,将会调用托管对象的析构函数。语义和map/reduce过程非常相近。我们只需自己实现讲请求划分多个任务即可。示例过程如下:
   
    l  定义请求托管对象,加入我们需要在10个文件中搜索“oh nice”字符串出现的次数,定义托管结构体如下:
   
    struct reducer{
   
    void set_result(int index, long result) {
   
    m_result[index] = result;
   
    }
   
    ~reducer(){
   
    long total = 0;
   
    for (int i = 0; i < sizeof(m_result); ++i){
   
    total += m_result[i];
   
    }
   
    //! post total to somewhere
   
    }
   
    long m_result ;
   
    };
   
    l  定义执行任务的 worker
   
    void worker_t:exe(int index_, shared_ptr<reducer> ret) {
   
    ret->set_result(index, 100);
   
    }
   
    l  将任务分割后,投递给不同的worker
   
    shared_ptr<reducer> ret(new reducer());
   
    for (int i = 0; i < 10; ++i)
   
    {
   
    task_queue[i]->post(boost::bind(&worker_t:exe, i, ret));
   
    }

      

首页 上一页 1 2 3 4 5 下一页 尾页 4/5/5
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇C/C++函数调用的几种方式 下一篇C++中数据共享的实现机制

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: