zoukankan      html  css  js  c++  java
  • boost::asio::io_service::run学习笔记

    一, 初始化一个tcp::socket socket_(io_service)时,最终会调用 io_service.init_task(),

     1 void task_io_service::init_task()
     2 {
     3   mutex::scoped_lock lock(mutex_);
     4   if (!shutdown_ && !task_)
     5   {
     6     task_ = &use_service<reactor>(this->get_io_service());
     7     op_queue_.push(&task_operation_);
     8     wake_one_thread_and_unlock(lock);
     9   }
    10 }

    从上面可以看出init_task时初始化一个task_,并把一个tak_operation_加入io_service公共队列op_queue中;( 1,task_就是一个epoll_reactor对象在其run函数中调用epoll_wait;   2,task_operation_是operation的一个派生类; )

    然后唤醒一个空闲线程来执行op_queue中的任务;

    二,假设用同一个io_service开启了4个线程,每个线程执行io_service::run()

    1,io_service::run()在linux下最终会调用task_io_service::run(),进行调用task_io_service::do_run_one()函数

    Thread_1在运行run()时发现io_service.op_queue不为空,取出一个op,发现此op就是之前投递的task_operation_则调用task_->run(),来调用epoll_wait();

    此时线程的运行情况是这样的:


    Thread_1——————————————epoll_wait…
    Thread_2——————————————阻塞
    Thread_3——————————————阻塞
    Thread_4——————————————阻塞

    注意:Thread_1的task_->run()执行完后,会把通过epoll_wait放入当前线程私有队列的任务,全部移到io_service.op_queue中,同时会把task_operation_放入到io_service.op_queue队列末尾;

    2,假设经过很久以后epoll_wait监听到了很多任务,比如有5个IO任务,一个task_operation_,则线程的运行情况是这样的

    Thread_1——————从op_queue中取出一个Op1,检查公共队列是否为空,不为空唤醒一个空闲线程,不是task, o->complete—————running......
    Thread_2——————从op_queue中取出一个Op2,检查公共队列是否为空,不为空唤醒一个空闲线程,不是task, o->complete—————running......
    Thread_3——————从op_queue中取出一个Op3,检查公共队列是否为空,不为空唤醒一个空闲线程,不是task, o->complete—————running......
    Thread_4——————从op_queue中取出一个Op4,检查公共队列是否为空,不为空唤醒一个空闲线程,不是task, o->complete—————running......

    ......


    Thread_1——————从op_queue中取出一个Op5,检查公共队列是否为空,不为空唤醒一个空闲线程,不是task, o->complete()—————running......
    Thread_2——————从op_queue中取出一个Op6,检查公共队列是否为空,已经为空,是task,task_->run()—————epoll_wait......
    Thread_3——————公共队列为空—————waiting......
    Thread_4——————公共队列为空—————waiting......

    三,上面就是io_service的简单运行过程

    通过上面可以发现以下几点信息:

    1,每一个io_service都有一个公共队列op_queue_,供多线程访问;

    2,每一个线程都有一个私有队列private_op_queue_;

    3,epoll_wait是在多线程间来回切换的,只有一个线程会执行epoll_wait;

    4,每一个io_service对应一个epoll_wait;

  • 相关阅读:
    单点登录的实现原理
    Entity Framework添加记录时获取自增ID值
    linq to entity查询,日期格式化
    Linq之GroupBy用法
    IIS HTTPS CA
    CallContext和多线程
    windows平台 culture name 详细列表
    如何在WCF中集成unity
    .NET MVC 依赖注入 来龙去脉
    apache虚拟主机安装注意事项
  • 原文地址:https://www.cnblogs.com/guoliushui/p/9635602.html
Copyright © 2011-2022 走看看