1.0 task_io_service

在boost.asio源码阅读(1)中,代码已经查看到task_io_service中。

具体的操作调用void task_io_service::init_task()

本文从init_task出发,查看到底basic_socket_acceptor的创建对task_io_service产生了什么影响.

1.1 init_task

直接上代码

void task_io_service::init_task()
{
mutex::scoped_lock lock(mutex_);
if (!shutdown_ && !task_)
{
1. task_ = &use_service<reactor>(this->get_io_service());
2. op_queue_.push(&task_operation_);
3. wake_one_thread_and_unlock(lock);
}
}
  1. 创建task_,其实task_就是epoll_reactor.
  2. 将成员task_operation_放入队列
  3. 唤醒一个线程,并对当前操作解锁。

    这里能够明确io_service使用了同步队列op_queue(lock->入队->唤醒->unlock),在basic_socket_acceptor

    创建时,将task_operation_放入队列,在io_service->run()中,这个变量将会被操作.

1.2 task_io_service::run

直奔主题

std::size_t task_io_service::run(boost::system::error_code& ec)
{
// ......
thread_info this_thread;
this_thread.private_outstanding_work = 0;
// ......
for (; do_run_one(lock, this_thread, ec); lock.lock())
//......
}

thread_info 内部含有一个队列,也就是说在多线程调用io_service::run的时候

每一个线程将会具有自己的私有队列。

std::size_t task_io_service::do_run_one
{
while (!stopped_)
{
if (!op_queue_.empty())
{
// Prepare to execute first handler from queue.
operation* o = op_queue_.front();
op_queue_.pop();
bool more_handlers = (!op_queue_.empty()); 1. if (o == &task_operation_)
{
task_interrupted_ = more_handlers; if (more_handlers && !one_thread_)
wakeup_event_.unlock_and_signal_one(lock);
else
lock.unlock(); 2. task_cleanup on_exit = { this, &lock, &this_thread };
(void)on_exit;
task_->run(!more_handlers, this_thread.private_op_queue);
}
else
{
std::size_t task_result = o->task_result_; if (more_handlers && !one_thread_)
wake_one_thread_and_unlock(lock);
else
lock.unlock(); // Ensure the count of outstanding work is decremented on block exit.
4. work_cleanup on_exit = { this, &lock, &this_thread };
(void)on_exit; // Complete the operation. May throw an exception. Deletes the object.
o->complete(*this, ec, task_result); return 1;
}
}
else
{
wakeup_event_.clear(lock);
5. wakeup_event_.wait(lock);
}
} return 0;
}
  1. 如果当前操作的队列内容是task_operation_则最后会进入到task_->run也就是epoll_wait。

    同时,如果当前队列不为空且是多线程的时候,会继续唤醒线程来执行操作,避免epoll_wait阻赛带来的延迟(虽然可以打断)。

    到这里可以知道basic_socket_acceptor的创建使io_service->run的时候可以进入epoll_wait来处理相关的事件,
  2. 和line4相同,都是在定义一个变量后,执行对应的析构操作。同时将线程的私有队列的内容,添加到公有队列op_queue_中,最后将刚才出队的task_operation_重新加到队尾(task_cleanup),使io_service在处理完队列之前的事件后,再次进入到task->run中。
  3. line5表示在队列为空时,线程进入睡眠等待唤醒。

2. 小结

  1. 在本文中,可以知道basic_socket_acceptor的创建使io_service在循环事件时能够进入到epoll_wait。

    当然如果这时使用者将acceptor删除也不能改变io_service->run本身的逻辑,也就是说,如果acceptor不在需要,io_service要么停止或者重新开始,避免epoll_wait上面不必要的效率损失。
  2. task_io_service本身有一个公共队列,同时每一个执行线程有自己的私有队列,在每次处理事件之前,会将

    私有队列的内容先加入到公有队列中。在某种程度上,公有队列的内容要比私有队列的优先级高些。
  3. asio的所有事件,最后都会回到公有队列中等待被执行。

boost.asio源码阅读(2) - task_io_service的更多相关文章

  1. boost.asio源码阅读(1) - 从chat_server开始

    1. 关于示例代码 chat 先从简单的入手, 在如下路径:boost_1_63_0/libs/asio/example/cpp11/chat中找到chat_server.cpp 查看其成员, pri ...

  2. boost.asio源码剖析(一) ---- 前 言

    * 前言 源码之前,了无秘密.                                                       ——侯捷 Boost库是一个可移植.提供源代码的C++库,作 ...

  3. boost.asio源码剖析(三) ---- 流程分析

    * 常见流程分析之一(Tcp异步连接) 我们用一个简单的demo分析Tcp异步连接的流程: #include <iostream> #include <boost/asio.hpp& ...

  4. boost.asio源码剖析(五) ---- 泛型与面向对象的完美结合

    有人说C++是带类的C:有人说C++是面向对象编程语言:有人说C++是面向过程与面向对象结合的语言.类似的评论网上有很多,虽然正确,却片面,是断章取义之言. C++是实践的产物,C++并没有为了成为某 ...

  5. boost.asio源码剖析(四) ---- asio中的泛型概念(concepts)

    * Protocol(通信协议) Protocol,是asio在网络编程方面最重要的一个concept.在第一章中的levelX类图中可以看到,所有提供网络相关功能的服务和I/O对象都需要Protoc ...

  6. boost.asio源码剖析(二) ---- 架构浅析

    * 架构浅析 先来看一下asio的0层的组件图.                     (图1.0) io_object是I/O对象的集合,其中包含大家所熟悉的socket.deadline_tim ...

  7. boost.asio源码剖析

    一. 前 言二. 架构浅析三. 流程分析     * 常见流程分析之一(Tcp异步连接)      * 常见流程分析之二(Tcp异步接受连接)      * 常见流程分析之三(Tcp异步读写数据)   ...

  8. FreeCAD源码阅读笔记

    本文目标在于记录在FreeCAD源码阅读中了解到的一些东西. FreeCAD编译 FreeCAD源码的编译最好使用官方提供的LibPack,否则第三方库难以找全,找到之后还需要自己编译,此外还不知道C ...

  9. 【原】FMDB源码阅读(三)

    [原]FMDB源码阅读(三) 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 FMDB比较优秀的地方就在于对多线程的处理.所以这一篇主要是研究FMDB的多线程处理的实现.而 ...

随机推荐

  1. venom结合Metasploit绕过360安全卫士

    原理:msfvenom是msfpayload和msfencode的结合体,利用msfvenom生成shellcode,venom生成工具使用了 一些 Veil-Evasion.py, unicorn. ...

  2. Java程序性能优化读书笔记(一):Java性能调优概述

    程序性能的主要表现点: 执行速度:程序的反映是否迅速,响应时间是否足够短 内存分配:内存分配是否合理,是否过多地消耗内存或者存在内存泄漏 启动时间:程序从运行到可以正常处理业务需要花费多少时间 负载承 ...

  3. Vue框架Element的事件传递broadcast和dispatch方法分析

    前言 最近在学习饿了么的Vue前端框架Element,发现其源码中大量使用了$broadcast和$dispatch方法,而Element使用的是Vue2.0版本,众所周知在Vue 1.0升级到2.0 ...

  4. Ubuntu 14.04 64bit 系统下打开PHPadmin时出现缺少mysqli|mysql 扩展的解决方法(php5)

    网上找了很多方法,都是翻来覆去的抄袭. 都在说把 /etc/php5/apache2/php.ini 下面的  ;extension=php_mysqli.dll  前面的 ; 注释符号去掉 再重启 ...

  5. Xamarin+Prism开发详解八:自动化测试之NUnit实践

    自动化测试很重要!很重要!以前多是手动测试,没有写过测试用例.这样的结果就是发现bug改了之后关联的其他功能又要从新测一遍.这样既浪费时间与成本,而且很无聊.之所以选择NUnit是公司需要,现在.ne ...

  6. BZOJ 1103: [POI2007]大都市meg(dfs序,树状数组)

    本来还想链剖的,结果才发现能直接树状数组的= = 记录遍历到达点与退出点的时间,然后一开始每个到达时间+1,退出时间-1,置为公路就-1,+1,询问直接点1到该点到达时间求和就行了- - CODE: ...

  7. WP8.1应用双击返回键退出程序。

    #region 双击退出程序代码 //双击HardwareButtons.BackPressed: //出现退出提示窗口: //“确定”退出,“取消”返回什么也不做: private async vo ...

  8. React Native填坑之旅 -- 使用iOS原生视图(高德地图)

    在开发React Native的App的时候,你会遇到很多情况是原生的视图组件已经开发好了的.有的是系统的SDK提供的,有的是第三方试图组件,总之你的APP可以直接使用的原生视图是很多的.React ...

  9. 【转】对于HttpClient和HtmlUnit的理解

    原文地址:http://www.haohaoblog.com/?p=1327&utm_source=tuicool 做Java编程的人其实,很多不懂SEO,也不知道如何让百度收录等等,当然,对 ...

  10. Xcode的中常用到的快捷键,印象笔记中常用到的快捷键

    Xcode提供了很多快捷键,灵活使用快捷键可以提升开发效率.但对于初学者来说,一次性的去记住并掌握如此多的快捷键显然是不现实的,本文就是来帮助大家了解在iOS开发过程中,使用最频繁的一些快捷键. 1. ...