以下是对 BackgroundTask::Schedule
函数代码的详细解释:
void BackgroundTask::Schedule(std::function<void()> callback) {
std::lock_guard<std::mutex> lock(mutex_);
if (active_tasks_ >= 30) {
int free_sram = heap_caps_get_free_size(MALLOC_CAP_INTERNAL);
if (free_sram < 10000) {
ESP_LOGW(TAG, "active_tasks_ == %u, free_sram == %u", active_tasks_.load(), free_sram);
}
}
active_tasks_++;
main_tasks_.emplace_back([this, cb = std::move(callback)]() {
cb();
{
std::lock_guard<std::mutex> lock(mutex_);
active_tasks_--;
if (main_tasks_.empty() && active_tasks_ == 0) {
condition_variable_.notify_all();
}
}
});
condition_variable_.notify_all();
}
整体功能概述
BackgroundTask::Schedule
函数的主要功能是将一个回调函数添加到后台任务队列中等待执行。在添加任务之前,会检查当前活跃任务的数量和系统的可用内存,若活跃任务过多且内存不足会输出警告信息。添加任务后,会通知所有等待的线程有新任务加入。
代码逐行解释
void BackgroundTask::Schedule(std::function<void()> callback) {
- 定义一个名为
Schedule
的成员函数,它属于BackgroundTask
类。该函数接受一个std::function<void()>
类型的参数callback
,即一个无参数、无返回值的可调用对象。
std::lock_guard<std::mutex> lock(mutex_);
- 创建一个
std::lock_guard
对象lock
,用于自动管理互斥锁mutex_
。std::lock_guard
在构造时会自动锁定互斥锁,在析构时会自动解锁,确保在lock
对象的生命周期内,互斥锁是被锁定的,从而保证线程安全。
if (active_tasks_ >= 30) {
int free_sram = heap_caps_get_free_size(MALLOC_CAP_INTERNAL);
if (free_sram < 10000) {
ESP_LOGW(TAG, "active_tasks_ == %u, free_sram == %u", active_tasks_.load(), free_sram);
}
}
- 检查当前活跃任务的数量
active_tasks_
是否大于等于30。- 如果是,则调用
heap_caps_get_free_size(MALLOC_CAP_INTERNAL)
函数获取系统内部可用的SRAM(静态随机存取存储器)大小。 - 若可用SRAM小于10000字节,使用
ESP_LOGW
函数输出警告信息,显示当前活跃任务的数量和可用SRAM的大小。
- 如果是,则调用
active_tasks_++;
- 增加活跃任务的数量,表示有一个新任务即将被添加到队列中。
main_tasks_.emplace_back([this, cb = std::move(callback)]() {
- 使用
emplace_back
方法将一个新的 lambda 表达式添加到main_tasks_
任务队列的末尾。- 这个 lambda 表达式捕获了
this
指针和callback
(使用std::move
进行移动语义,避免不必要的复制)。 - 该 lambda 表达式代表一个任务,当被调用时会执行传入的
callback
函数。
- 这个 lambda 表达式捕获了
cb();
- 在 lambda 表达式内部,调用传入的
callback
函数,执行具体的任务。
{
std::lock_guard<std::mutex> lock(mutex_);
active_tasks_--;
if (main_tasks_.empty() && active_tasks_ == 0) {
condition_variable_.notify_all();
}
}
- 再次创建一个
std::lock_guard
对象lock
来锁定互斥锁mutex_
,以确保对active_tasks_
的操作是线程安全的。 - 任务执行完毕后,减少活跃任务的数量。
- 检查任务队列
main_tasks_
是否为空且活跃任务数量为0。如果是,则调用condition_variable_.notify_all()
通知所有等待的线程,此时没有活跃任务且任务队列为空。
});
condition_variable_.notify_all();
- 最后,调用
condition_variable_.notify_all()
通知所有等待的线程,有新任务被添加到了任务队列中。