设为首页 加入收藏

TOP

C++编程知识:多线程编程总结(二)
2019-03-18 16:08:52 】 浏览:133
Tags:编程 知识 线程 总结
eva l tv; };
#define PROFILER() profiler(__FUNCTION__)

Cost 应该被投递到性能统计管理器中,该管理器定时讲性能统计数据输出到文件中。

4 Lambda 编程

使用foreach 代替迭代器

很多编程语言已经内建了foreach,但是c++还没有。所以建议自己在需要遍历容器的地方编写foreach函数。习惯函数式编程的人应该会非常钟情使用foreach,使用foreach的好处多多少少有些。

但主要是编程哲学上层面的。

示例:

void user_mgr_t::foreach(boost::function 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[10];

};

●l 定义执行任务的 worker

void worker_t:exe(int index_, shared_ptr ret) {

ret->set_result(index, 100);

}

●l 将任务分割后,投递给不同的worker

shared_ptr ret(new reducer());

for (int i = 0; i < 10; ++i) { task_queue[i]->post(boost::bind(&worker_t:exe, i, ret));

}

博主是一个有着7年工作经验的架构师,对于c++,自己有做资料的整合,一个完整学习C语言c++的路线,学习资料和工具。可以进我的Q群7418,18652领取,免费送给大家。希望你也能凭自己的努力,成为下一个优秀的程序员!另外博主的微信公众号是:C语言编程基地,欢迎关注!

首页 上一页 1 2 下一页 尾页 2/2/2
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇[ZJOI2007] 捉迷藏 下一篇使用epoll实现聊天室功能,同时比..

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目