小智机器人相关函数解析,BackgroundTask::Schedule (***)将一个回调函数添加到后台任务队列中等待执行

以下是对 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 函数。
        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() 通知所有等待的线程,有新任务被添加到了任务队列中。