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. CODEFORCES 125E MST Company 巧用Kruskal算法

    题意:给定一个带权边无向图,求最小生成树,且满足第一个节点的度为固定的k 无解则输出-1 数据规模: 节点数n和限制k<=5000 边数m<=10^5 时限8sec 思路: 首先时限比较宽 ...

  2. win10下VS2015局域网调试配置

    一.前言 换win10页挺久了一直没有使用 IISExpress 的局域网功能,今天一使用才发现 win10 比起 win7 下配置多了许多坑. 二.配置步骤 首先我们先来拿到本机 ip 地址 打开命 ...

  3. 制作jar文件

    一.制作可运行jar文件 使用java的swing.awt制作了一个简单的界面交互模块.程序打成jar包后,能双击运行,制作过程: 1.eclipse →properties →Export,选择ja ...

  4. shell脚本,符号

    在shell中常用的特殊符号罗列如下: # ;   ;; . , / \\ 'string'| !   $   ${}   $? $$   $* \"string\"* **   ...

  5. Swift 2.0 UIAlertView 和 UIActionSheet 的使用

    在 IOS 9.0 之后, UIAlertView  是 给废弃了的,虽然你要使用的话,暂时还是可以的,但是在 9.0 之后,IOS 推荐大家使用的是  UIAlertController 这个控制器 ...

  6. matlab 逻辑数组及其应用

    这几天学习了matlab的逻辑数组功能,总的感觉就有两点: 第一,通过对原来的数组a进行逻辑判断后得到逻辑数组b 第二,逻辑数组进行某种运算符操作又回到原数组类型 第三,利用逻辑数组mask功能 测试 ...

  7. C# 获取文件MD5与SHA1

    之前刚开始学习编程的时候,总想着自己写一些小软件小工具. 而这个就是经典的文件MD5校验,顺便加上了一个SHA1. 在网络上下载一些东西时,会有作者提供MD5值. 它的作用就在于我们可以在下载该软件后 ...

  8. 浅谈PHP的CI框架(一)

    作为前端开发人员,掌握一门后端语言是必不可少的,PHP的CI框架是一个快速开发框架,基于MVC,比较接近原生PHP,在原有的PHP代码上封装了许多类,易上手,容易扩展,适用于小项目,并且CI的文档及案 ...

  9. 简学Python第四章__装饰器、迭代器、列表生成式

    Python第四章__装饰器.迭代器 欢迎加入Linux_Python学习群  群号:478616847 目录: 列表生成式 生成器 迭代器 单层装饰器(无参) 多层装饰器(有参) 冒泡算法 代码开发 ...

  10. zabbix安装详解

    关于zabbix及相关服务软件版本: Linux:centos 6.6 nginx:1.9.15 MySQL:5.5.49 PHP:5.5.35 一.安装nginx: 安装依赖包: yum -y in ...