Skip to content

Utils_ThreadPauser

SweerItTer edited this page Feb 21, 2026 · 4 revisions

ThreadPauser API 文档

概述

ThreadPauser 是 utilsCore Utils 模块的核心类,提供 Linux 平台特供的线程暂停和恢复功能,基于 eventfd 实现。

职责

  • 控制线程暂停和恢复
  • 真正的内核级阻塞,暂停时不消耗 CPU
  • 零锁设计,无锁竞争
  • 支持超时唤醒

适用场景

  • 动态调整线程运行
  • 资源受限时暂停线程
  • 批量处理控制
  • 线程调度

依赖关系

  • 依赖: Linux eventfd 系统调用
  • 被依赖: 异步任务处理等模块

平台限制

  • 仅支持 Linux 平台
  • 如果需要跨平台支持,请使用条件变量版本

类分析

ThreadPauser 类

职责与用途

ThreadPauser 是线程暂停的封装类,提供:

  • 基于 eventfd 的高性能暂停/恢复
  • 零锁设计
  • 支持暂停状态检查
  • 支持超时唤醒

设计模式

  • PImpl 惯用法: 隐藏实现细节
  • RAII: 自动管理资源

公共 API 方法

构造函数

ThreadPauser();
~ThreadPauser();

// 移动构造函数
ThreadPauser(ThreadPauser&& other) noexcept;

// 移动赋值运算符
ThreadPauser& operator=(ThreadPauser&& other) noexcept;

// 禁用拷贝构造和拷贝赋值
ThreadPauser(const ThreadPauser&) = delete;
ThreadPauser& operator=(const ThreadPauser&) = delete;

参数说明:

  • other: 要移动的源对象(移动操作后源对象处于有效但未定义状态)

返回值:

  • 移动构造函数:无
  • 移动赋值运算符:返回 *this 的引用

所有权归属:

  • ThreadPauser 拥有内部资源的所有权
  • 移动操作后,资源所有权从源对象转移到目标对象

异常:

  • 默认构造函数会在 eventfd 创建失败时抛出std::system_error
  • 移动构造函数和移动赋值运算符为 noexcept,保证不抛出异常

注意事项:

  1. 构造时创建 eventfd
  2. 初始状态为未暂停
  3. 支持移动语义,禁止拷贝
  4. 移动操作后,源对象处于有效但未定义状态(通常为空状态)
  5. 移动构造函数和移动赋值运算符保证不抛出异常,适合在容器中使用

使用例程:

// 默认构造
ThreadPauser pauser;

// 移动构造
ThreadPauser pauser2 = std::move(pauser);

// 移动赋值
ThreadPauser pauser3;
pauser3 = std::move(pauser2);

// 在容器中使用
std::vector<ThreadPauser> pausers;
pausers.emplace_back();  // 使用移动语义

pause() - 暂停线程

void pause();

参数说明: 无

返回值: 无

所有权归属:

  • 无所有权转移

注意事项:

  1. 线程将在下一次调用 wait_if_paused() 时阻塞
  2. 线程安全操作
  3. 真正的内核级阻塞,不消耗 CPU

使用例程:

pauser.pause();

resume() - 恢复线程

void resume();

参数说明: 无

返回值: 无

所有权归属:

  • 无所有权转移

异常:

  • 如果系统调用失败且未关闭,可能抛出 std::system_error

注意事项:

  1. 唤醒所有等待的线程
  2. 线程安全操作
  3. 通过 eventfd 实现唤醒

使用例程:

pauser.resume();

toggle() - 切换暂停状态

void toggle();

参数说明: 无

返回值: 无

所有权归属:

  • 无所有权转移

注意事项:

  1. 暂停时恢复,未暂停时暂停
  2. 线程安全操作

使用例程:

pauser.toggle();  // 切换状态

wait_if_paused() - 等待(如果已暂停)

void wait_if_paused();

参数说明: 无

返回值: 无

所有权归属:

  • 无所有权转移

异常:

  • 如果系统调用失败且未关闭,可能抛出 std::system_error

注意事项:

  1. 如果已暂停则阻塞,否则立即返回
  2. 真正的内核级阻塞
  3. 线程安全操作

使用例程:

// 在工作线程中
while (running) {
    pauser.wait_if_paused();  // 如果已暂停则阻塞
    
    // 处理任务...
    do_work();
}

wait_if_paused_for() - 带超时的等待

bool wait_if_paused_for(int timeout_ms);

参数说明:

  • timeout_ms (输入): 超时时间(毫秒)

返回值:

  • true: 等待成功(恢复或未暂停)
  • false: 超时

所有权归属:

  • 无所有权转移

注意事项:

  1. 支持超时唤醒
  2. 线程安全操作

使用例程:

// 在工作线程中
while (running) {
    if (!pauser.wait_if_paused_for(1000)) {
        printf("Still paused, doing other work\n");
    }
    
    // 处理任务...
    do_work();
}

is_paused() - 检查是否暂停

bool is_paused() const;

参数说明: 无

返回值:

  • true: 已暂停
  • false: 未暂停

所有权归属:

  • 只读访问

注意事项:

  1. 线程安全操作
  2. 使用原子操作

使用例程:

if (pauser.is_paused()) {
    printf("Thread is paused\n");
}

close() - 关闭控制器

void close();

参数说明: 无

返回值: 无

所有权归属:

  • 关闭后对象不可再使用

注意事项:

  1. 唤醒所有等待的线程
  2. 调用后对象不可再使用
  3. 线程安全操作

使用例程:

pauser.close();  // 关闭控制器

is_closed() - 检查是否已关闭

bool is_closed() const;

参数说明: 无

返回值:

  • true: 已关闭
  • false: 未关闭

所有权归属:

  • 只读访问

注意事项:

  1. 线程安全操作
  2. 只读操作

使用例程:

if (pauser.is_closed()) {
    printf("Controller is closed\n");
}

内部实现

PImpl 惯用法

ThreadPauser 使用 PImpl 惯用法隐藏实现细节:

class ThreadPauser {
private:
    class Impl;
    std::unique_ptr<Impl> impl_;
};

eventfd 实现

基于 Linux eventfd 系统调用实现:

int eventfd(unsigned int initval, int flags);

特点:

  • 内核级阻塞
  • 零锁设计
  • 高性能

线程安全说明

同步机制

  • 状态管理: 使用原子操作
  • eventfd: 内核级同步

线程安全建议

  • 可以并发调用 pause()
  • 可以并发调用 resume()
  • 所有操作都是线程安全的

典型使用场景

场景 1: 基本使用

ThreadPauser pauser;

// 工作线程
std::thread worker([&]() {
    while (running) {
        pauser.wait_if_paused();  // 如果已暂停则阻塞
        
        // 处理任务...
        do_work();
    }
});

// 暂停线程
pauser.pause();

// 恢复线程
pauser.resume();

worker.join();

场景 2: 超时等待

ThreadPauser pauser;

// 工作线程
std::thread worker([&]() {
    while (running) {
        if (!pauser.wait_if_paused_for(1000)) {
            printf("Still paused, doing other work\n");
        }
        
        // 处理任务...
        do_work();
    }
});

场景 3: 切换状态

ThreadPauser pauser;

// 工作线程
std::thread worker([&]() {
    while (running) {
        pauser.wait_if_paused();
        do_work();
    }
});

// 切换暂停状态
pauser.toggle();  // 暂停
pauser.toggle();  // 恢复

场景 4: 资源受限时暂停

ThreadPauser pauser;

// 监控线程
std::thread monitor([&]() {
    while (running) {
        int memory_usage = get_memory_usage();
        
        if (memory_usage > 90) {
            printf("High memory usage, pausing worker\n");
            pauser.pause();
        } else if (memory_usage < 70 && pauser.is_paused()) {
            printf("Memory usage normal, resuming worker\n");
            pauser.resume();
        }
        
        sleep(1);
    }
});

while(running) {
    pauser.wait_if_paused();
    // do something
}

场景 5: 关闭控制器

ThreadPauser pauser;

// 工作线程
std::thread worker([&]() {
    while (running) {
        pauser.wait_if_paused();
        do_work();
    }
});

// 关闭控制器,唤醒所有等待的线程
pauser.close();

注意事项

  1. 平台限制: 仅支持 Linux 平台
  2. eventfd: 依赖 Linux eventfd 系统调用
  3. 内核级阻塞: 真正的内核级阻塞,不消耗 CPU
  4. 零锁设计: 无锁竞争
  5. 关闭后不可用: close() 后对象不可再使用
  6. 线程安全: 所有操作都是线程安全的
  7. 异常处理: 注意处理可能抛出的异常
  8. PImpl: 使用 PImpl 惯用法隐藏实现细节

相关文档


参考资料

主页

API 文档

DMA 模块

DRM 模块

NET 模块

V4L2 模块

V4L2Param 模块

RGA 模块

MPP 模块

Sys 模块

Mouse 模块

Utils 模块

Clone this wiki locally