anbox 使用情况_Anbox 实现分析 2:I/O 模型

Anbox 运行时主要由两个分开的实例构成,即容器管理器 ContainerManager 和会话管理器 SessionManager,但无论是 ContainerManager 还是 SessionManager,所做的最重要的事情就是处理网络 I/O 事件了。I/O 模型指一个应用处理 I/O 事件的整体框架设计,对于 Anbox 而言主要是处理各种网络 I/O 事务的整体框架设计。ContainerManager 和 SessionManager 基于一个相同的 I/O 模型运行,为了获得对 Anbox 整体行为设计的理解,有必要对其 I/O 模型有个整体的认识。

I/O 模型

Anbox 的 I/O 模型基于 boost.asio 构建。Anbox 中所有的 I/O 事件,在一个线程池中,通过一个 boost::asio::io_service 对象来派发并处理。Anbox 用 anbox::Runtime 类封装一个 boost::asio::io_service 对象,并管理执行任务的线程池。

anbox::Runtime 类的定义(位于 anbox/src/anbox/runtime.h)如下:namespace anbox {// We bundle our "global" runtime dependencies here, specifically// a dispatcher to decouple multiple in-process providers from one// another , forcing execution to a well known set of threads.class Runtime : public DoNotCopyOrMove,                public std::enable_shared_from_this { public:  // Our default concurrency setup.

static constexpr const std::uint32_t worker_threads = 8;  // create returns a Runtime instance with pool_size worker threads

// executing the underlying service.

static std::shared_ptr create(      std::uint32_t pool_size = worker_threads);  // Tears down the runtime, stopping all worker threads.

~Runtime() noexcept(true);  // start executes the underlying io_service on a thread pool with

// the size configured at creation time.

void start();  // stop cleanly shuts down a Runtime instance.

void stop();  // to_dispatcher_functional returns a function for integration

// with components that expect a dispatcher for operation.

std::function)> to_dispatcher_functional();  // service returns the underlying boost::asio::io_service that is executed

// by the Runtime.

boost::asio::io_service& service(); private:  // Runtime constructs a new instance, firing up pool_size

// worker threads.

Runtime(std::uint32_t pool_size);  std::uint32_t pool_size_;

boost::asio::io_service service_;

boost::asio::io_service::strand strand_;

boost::asio::io_service::work keep_alive_;  std::vector<:thread> workers_;

};

}  // namespace anbox

anbox::Runtime 类封装了一个 boost::asio::io_service 对象及多个工作线程 std::thread,它还继承 std::enable_shared_from_this 以获得从 this 指针创建智能指针 std::shared_ptr 的能力,同时继承了 DoNotCopyOrMove,以禁掉类的拷贝和移动操作。

anbox::Runtime 类的实现(位于 anbox/src/anbox/runtime.cpp)如下:namespace {void exception_safe_run(boost::asio::io_service& service) {  while (true) {    try {

service.run();      // a clean return from run only happens in case of

// stop() being called (we are keeping the service alive with

// a service::work instance).

break;

} catch (const std::exception& e) {

ERROR("%s", e.what());

} catch (...) {

ERROR("Unknown exception caught while executing boost::asio::io_service");

}

}

}

}namespace anbox {std::shared_ptr Runtime::create(std::uint32_t pool_size) {  return std::shared_ptr(new Runtime(pool_size));

}

Runtime::Runtime(std::uint32_t pool_size)

: pool_size_{pool_size},

service_{pool_size_},

strand_{service_},

keep_alive_{service_} {}

Runtime::~Runtime() noexcept(true) {  try {

stop();

} catch (...) {    // Dropping all exceptions to satisfy the nothrow guarantee.

}

}void Runtime::start() {  for (unsigned int i = 0; i 

workers_.push_back(std::thread{exception_safe_run, std::ref(service_)});

}void Runtime::stop() {

service_.stop();  for (auto& worker : workers_)    if (worker.joinable())

worker.join();

workers_.clear();

}std::function)> Runtime::to_dispatcher_functional() {  // We have to make sure that we stay alive for as long as

// calling code requires the dispatcher to work.

auto sp = shared_from_this();  return [sp](std::function task) { sp->strand_.post(task); };

}

boost::asio::io_service& Runtime::service() { return service_; }

}  // namespace anbox

anbox::Runtime 类有两大职责,一是 boost::asio::io_service 对象的生命周期管理;二是向 boost::asio::io_service 中提交任务。

在 anbox::Runtime::start() 函数中创建并启动多个线程,执行一个执行 boost::asio::io_service::run() 函数的函数 exception_safe_run()。在 anbox::Runtime::stop() 函数中停掉 boost::asio::io_service 的执行。anbox::Runtime 的析够函数中,还会调用 stop() 函数停掉 boost::asio::io_service 的执行。anbox::Runtime 的类型为 boost::asio::io_service::work 的成员变量 keep_alive_ 也是用于管理 boost::asio::io_service 对象的生命周期的,该对象在析够时也会停掉 boost::asio::io_service 的执行。

对于不熟悉 boost 库的朋友来说,boost::asio::io_service 可以理解为一个 I/O 多路复用器,就像许多网络库通过 select/poll/epoll/kqueue 实现的那样,或者可以理解为以 Reactor 模式实现的网络库中的一个事件循环,可以向其中提交 I/O 任务、定时器及其它任务等。boost::asio::io_service::strand 可以理解为 boost::asio::io_service 中的一个特殊的子任务队列,该类保证向其提交的所有任务都不会并发执行,以此消除这些任务之间的同步问题。

anbox::Runtime::to_dispatcher_functional() 函数返回一个接收一个函数为参数的函数,返回的这个函数可以将它接收的函数作为一个 task,通过 boost::asio::io_service::strand 提交给 boost::asio::io_service 执行。anbox::Runtime::service() 返回 boost::asio::io_service 用于方便一些 boost I/O 组件,直接向该 io_service 中提交任务。

继承自 std::enable_shared_from_this 的 shared_from_this() 可以从 this 指针创建一个指向当前对象的 std::shared_ptr 智能指针。通过对标准库源码的分析,可以知道 std::enable_shared_from_this 的实现原理大体如下:std::enable_shared_from_this 有一个类型为 std::weak_ptr 的成员,该成员在首次创建指向对象的 std::shared_ptr 智能指针的时候会被初始化。shared_from_this() 函数被调用时,会从类型为 std::weak_ptr 的成员变量创建指向当前对象的 std::shared_ptr 智能指针。

Anbox 的 I/O 模型可以理解为,底层有 一个 多路复用器或事件循环 boost::asio::io_service,有一个包含了 8 个线程的线程池基于此 boost::asio::io_service 运行,处理 I/O 事件及其它各种类型的任务。

有了用于执行 I/O 事件处理程序的 boost::asio::io_service,接下来来看一下,Anbox 都会向其中提交哪些任务。

Anbox 需要处理如下这样一些网络 I/O 过程:监听 Unix 域 Socket 接受连接。Anbox 的 SessionManager 通过 Unix 域 Socket 与 ContainerManager 进行通信,同时也通过 Unix 域 Socket 与 ContainerManager 启动的 Android 容器内的应用程序通信。首先 ContainerManager 监听在特定位置的 Unix 域 Socket 上。随后 SessionManager 监听几个位置上的 Unix 域 Socket,然后请求 ContainerManager 启动 Android 容器,并将这几个 Unix 域 Socket 映射到容器内的 /dev/ 目录下。Android 容器启动后,一些进程,如 surfaceflinger、cameraservice 等连接这些 Unix 域 Socket,并通过这些 Unix 域 Socket 与 SessionManager 通信,进而操作宿主机的硬件设备。

监听 TCP Socket 接受连接。Anbox 的 SessionManager 作为容器中运行的 Android 与 ADB 进行通信的桥梁,它在与容器中运行的 Android 通过 Unix 域 Socket 通信的同时,也需要与宿主机上的 ADB 通信。SessionManager 通过 TCP 与宿主机上的 ADB 守护进程通信。如同模拟器等 Android 设备一样,SessionManager 遵从 ADB 的通信协议,在发起与 ADB 之间的 TCP 连接的同时,也需要监听一个 TCP 端口,等待 ADB 守护进程发起的连接,以完成整个 ADB 协议。

处理从监听的 Unix 域 Socket 接受的 Unix 域 Socket。监听的 Unix 域 Socket 接受新连接之后,需要将新创建的 Unix 域 Socket 提交给底层的 I/O 多路复用器,并为该 Socket 提供读写等 I/O 事件处理处理回调,以完成 Anbox 的应用逻辑。

处理从监听的 TCP Scoket 接受的 TCP Socket。监听的 TCP Socket 接受新连接之后,需要将新创建的 TCP Socket 提交给底层的 I/O 多路复用器,并为该 Socket 提供读写等 I/O 事件处理处理回调,以完成 Anbox 的应用逻辑。

发起一个到 TCP 服务器的连接。如前面提到的,Anbox 的 SessionManager 通过 TCP 连接与 ADB 守护进程通信,它会先发起一个到 ADB 守护进程的 TCP 连接。

发起一个到 Unix 域 Socket 服务的连接。Anbox 的 SessionManager 与 ContainerManager 之间通过 Unix 域 Socket 通信,SessionManager 会发起到 ContainerManager 监听的 Unix 域 Socket 服务的连接。

监听 Unix 域 Socket 接受连接

在 boost.asio 中,监听 Socket 并接受新连接,通过 acceptor 完成,对于具体的 Unix 域 Socket 而言,是通过 boost::asio::local::stream_protocol::acceptor。boost::asio::local::stream_protocol::acceptor 类对象在

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值