asio学习笔记2
来源:互联网 发布:ubuntu下移动文件夹 编辑:程序博客网 时间:2024/05/21 15:00
asio学习笔记2
继续写。。今天的讨论的主题是io_service::run函数什么时候会退出。
先上代码:
#include <boost/asio.hpp>#include <boost/thread.hpp>#include <iostream>int num = 0;void foo(){ std::cout << "hello " << ++num << std::endl;}int main(int argc, char* argv[]){ boost::asio::io_service ios; for (int i = 0; i < 10; ++i) { ios.post(foo); } std::cout << "执行run之前" << std::endl; ios.run(); std::cout << "run执行完毕" << std::endl; return 0;}
运行结果:
结果跟猜想的一样,其实所有事件都不过是在run函数中运行的,只要还有事件没完成,也没有出错,run函数是不会退出的。这是肯定的嘛,你又不开线程,又不想在任何地方阻塞本线程,本来就是不合理的。
如果你想让完成一个事件返回一次,可续选择用run_one,这样的话只要完成一个事件就会返回一次,而不是所有的都完成了才返回。使用run_one的话需要用配合stopped函数来判断是否所有时间都已经执行完了。其实run函数与下面的代码是一样的效果:
while (!ios.stopped()){ ios.run_one();}
另外当所执行的事件出错时,run函数也会退出或抛出异常。run函数和run_one函数都有两个重载,没有参数的run或run_one在遇到异常时自己也会会抛出boost::system::system_error异常,加了boost::system::error_code&参数的版本则会将错误信息写入该参数然后返回。不过我还一直没遇到过run函数抛出异常或者出错的情况,可能是用的太少了。
既然只要还有“任务”,run就不会退出,个人认为一个好的设计应该一直让我们的发动机有事情可做,一直到做完所有的事情然后退出,如下面的代码:
#include <boost/bind.hpp>#include <boost/asio.hpp>#include <boost/filesystem.hpp>#include <iostream>void async_dir(boost::asio::io_service& io, boost::filesystem::directory_iterator& di){ if (di == boost::filesystem::directory_iterator()) { return; } if (boost::filesystem::is_directory(di->path())) { boost::system::error_code ec; boost::filesystem::directory_iterator sub_di(di->path(),ec); if (!ec) { io.post(boost::bind(&async_dir, boost::ref(io), sub_di)); } else { std::cout << "遍历目录 " << di->path() << "出错,错误原因为:" << ec.message() << std::endl; } } std::cout << di->path() << std::endl; boost::system::error_code ec; ++di; io.post(boost::bind(&async_dir, boost::ref(io), di));}int main(int argc, char* argv[]){ boost::asio::io_service io; boost::filesystem::path p("C:\\"); boost::system::error_code ec; boost::filesystem::directory_iterator di(p,ec); int num = 0; if (!ec) { io.post(boost::bind(&async_dir, boost::ref(io), di)); } else { std::cout << "遍历目录 " << p << "出错,错误原因为:" << ec.message() << std::endl; } io.run(); return 0;}
这个是avplayer社区的microcai提出的一个异步递归的思想,不过他实现的那个是不会并行进行递归的,还用了coroutine,而且他第三擅长的事就是把简单的东西写的让人看不懂(我不说写的复杂),不熟悉的人可能看不明白,我也是看了jackarain的文章才搞明白的。这里就是在主函数中只post了一次,当函数完成或找到子文件夹时就再次调用post给发动机添加任务,直到所有的任务都已完成,就无需添加任务了,run函数自然就退出了。
虽然最好的做法是一直让发动机有事可做而不会退出,可是有的时候可能并不能做的这么完善,但是又不想让run退出,这时候你就需要boost::asio::io_service::work来帮忙,这个类的作用就是让io_service一直处于有事可做的状态而不会从run函数中退出,这样就避免了我们自己写循环重复调用run函数。当work析构而且没有任务的时候,run就会返回,测试代码如下:
#include <boost/asio.hpp>#include <boost/thread.hpp>#include <boost/thread.hpp>#include <iostream>boost::asio::io_service::work* work = NULL;void foo(){ std::cout << "hello" << std::endl;}void thd_fun(){ std::getchar(); delete work;}int main(int argc, char* argv[]){ boost::asio::io_service ios; ios.post(foo); work = new boost::asio::io_service::work(ios); boost::thread thd(thd_fun); boost::system::error_code ec; std::cout << "before run" << std::endl; ios.run(ec); std::cout << "after run" << std::endl; return 0;}
今天就先写这点,明天开始写几个基本的网络函数。
- asio学习笔记2
- asio学习笔记2
- boost asio学习笔记(2) echo 客户端
- Asio驱动开发学习笔记(2)
- ASIO库学习笔记
- asio学习笔记7
- asio学习笔记1
- asio学习笔记3
- asio学习笔记4
- asio学习笔记5
- asio学习笔记6
- Boost::asio 学习笔记
- asio的学习笔记
- boost asio io_service学习笔记
- boost asio io_service学习笔记
- boost asio io_service学习笔记
- boost asio io_service学习笔记
- boost asio io_service学习笔记
- Maven导出Project依赖的jar包
- hibernate注解之简介(一)
- 访问权限控制
- python django 建表时的问题
- JQuery学习笔记之过滤性选择器
- asio学习笔记2
- Android TextView跑马灯效果
- BEGINNING SHAREPOINT® 2013 DEVELOPMENT 第15章节--开发SP2013工作流应用程序 SPD的新功能
- PHP的几种运行模式
- hibernate学习从XML入手
- 一些常见的端口
- 【Leetcode】Rotate List (lastN)
- 第9周 项目3-3 编程输出星图(c)
- Mac下使用Cocos2d-x Lua加载Cocos Studio到处的Json文件和动画