Catalog
  1. 1. ThreadPool
    1. 1.1. Worker
    2. 1.2. Scheduler
    3. 1.3. 等待任务结果
  2. 2. IOThreadPool
    1. 2.1. IOWorker
    2. 2.2. 网络 IO
    3. 2.3. 定时任务
erizo(c++)工作线程以及IO线程-Licode系列NO.6

分析一下 erizo c++ 库中的工作线程和IO线程及线程管理。

ThreadPool

工作线程池, 类图如下。
TIM截图20200107195629.png

线程池维护了指定数量的 Worker 对象,按最小使用次数分配 Worker。

Worker

每个 Worker 对象启动了一个 boost::thread,线程内执行 boost::asio::io_service::run()。 内部调用 boost::asio::io_service::dispatch() 方法执行任务。

Scheduler

Worker 持有一个 Scheduler 对象来执行定时任务和周期性任务。Scheduler 会启动两个(硬编码)线程来执行任务。

Worker::scheduleEvery // 周期性任务
Worker::scheduleFromNow // 定时任务

等待任务结果

因为任务都是在独立线程中执行的,所以需要配合使用 boost::future & boost::promise 等待异步执行结果。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
boost::future<void> WebRtcConnection::asyncTask(
std::function<void(std::shared_ptr<WebRtcConnection>)> f) {
auto task_promise = std::make_shared<boost::promise<void>>();
std::weak_ptr<WebRtcConnection> weak_this = shared_from_this();
// 执行任务
worker_->task([weak_this, f, task_promise] {
if (auto this_ptr = weak_this.lock()) {
f(this_ptr);
}
// 任务结束后,设置返回值,这里是空
task_promise->set_value();
});

// 返回 future,调用方可以调用 then 方法设置回调函数,处理返回结果
return task_promise->get_future();
}

IOThreadPool

IO 工作线程池,类图如下。
TIM截图20200107195654.png

线程池维护了指定数量的 IOWorker 对象,按最小使用次数分配 IOWorker

IOWorker

IOWorker 用来调用 Nicer 库的接口, 也就是 ICE 部分和媒体数据收发部分。

每个 Worker 启动了一个 std::thread, 同时维护一个 Task 列表。线程中调用 NR_async_event_wait2 等待事件通知或者 100ms 超时时间, NR_async_timer_update_time 中执行定时任务, 最后执行 task 任务列表。

网络 IO

通过 NR_async_wait 将 socket fd 及其回调函数注册到监视列表, IOWorker 会循环调用 NR_async_event_wait2 来触发事件的回调函数。

回调函数:
nr_ice_socket_readable_cb 这个会调读取 ICE 消息以及通道建立成功后所传输的音视频包

定时任务

Author: 42
Link: http://blog.ikernel.cn/2020/01/07/erizo(c++)%E5%B7%A5%E4%BD%9C%E7%BA%BF%E7%A8%8B/
Copyright Notice: All articles in this blog are licensed under CC BY-NC-SA 4.0 unless stating additionally.

Comment