系列文章目录
第一篇 基于SRS 的 WebRTC 环境搭建
第二篇 基于SRS 实现RTSP接入与WebRTC播放
第三篇 centos下基于ZLMediaKit 的WebRTC 环境搭建
第四篇 WebRTC学习一:获取音频和视频设备
第五篇 WebRTC学习二:WebRTC音视频数据采集
第六篇 WebRTC学习三:WebRTC音视频约束
第七篇 WebRTC学习四:WebRTC常规视觉滤镜
第八篇 WebRTC学习五:从视频中提取图片
第九篇 WebRTC学习六:MediaStream 常用API介绍
第十篇 WebRTC学习七:WebRTC 中 STUN 协议详解
ZLMediaKit源码分析——[1] 开篇:基础库 ZLToolKit 之 onceToken 源码分析
文章目录
- 系列文章目录
- 前言
- 一、onceToken 类详解
- 1. RAII 机制介绍
- 2. onceToken 的作用
- 3. onceToken 的使用场景
- 4. onceToken 的代码实现
- 二、onceToken的作用
- 三、onceToken 在 ZLToolKit 中的真实使用例子
- 1.TaskExecutorInterface::sync 函数
- 2.TaskExecutorInterface::sync_first 函数
- 四、测试用例
- 1. 带构造和析构函数的测试用例
- 2. 简化版异步任务执行测试用例
- 3. 带捕获异常的测试用例
- 总结
前言
ZLMediaKit 是一款功能强大的开源音视频流处理项目,它支持多种音视频协议,能够实现音视频的推流、拉流、转码等多种功能,广泛应用于直播、视频会议等领域。而 ZLToolKit 作为其基础工具库,提供了许多通用的工具类和函数,如网络编程、内存管理、线程池等,这些工具类和函数为 ZLMediaKit 的开发提供了便利,提高了开发效率。
onceToken类就是ZLToolKit 中的一部分,ZLMediaKit 源码中多处使用了onceToken类,理解它的设计和使用方法,将有助于我们更好地理解 ZLMediaKit 的源码。
一、onceToken 类详解
1. RAII 机制介绍
AII 是一种在 C++ 中广泛应用的编程技术,其核心思想是将资源的生命周期与对象的生命周期绑定在一起。当对象被创建时,资源被获取;当对象被销毁时,资源被自动释放。这种机制利用了 C++ 语言的析构函数特性,确保资源在任何情况下(包括异常抛出)都能被正确释放,从而避免了资源泄漏的问题。
例如,在 C++ 中使用 std::unique_ptr 管理动态分配的内存就是 RAII 机制的一个典型应用:
#include <iostream>
#include <memory>int main() {std::unique_ptr<int> ptr(new int(42));std::cout << *ptr << std::endl;// 当 ptr 离开作用域时,其析构函数会自动释放内存return 0;
}
2. onceToken 的作用
onceToken 类正是基于 RAII 原则实现的。它的主要作用是在对象构造时执行一个操作,在对象析构时执行另一个操作,确保资源的正确释放,即使在发生异常的情况下也能保证资源的清理。
3. onceToken 的使用场景
确保操作只执行一次:无论操作是在 onceToken 对象析构时自动触发,还是通过手动调用相关方法触发,都不会出现重复执行的情况。
资源管理:在获取资源后,需要确保在对象生命周期结束时释放资源,例如文件句柄、网络连接等。使用 onceToken 可以方便地实现资源的自动释放。
异常安全:在执行一系列操作时,需要确保某些操作在异常发生时也能被执行,例如解锁互斥锁、释放信号量等。onceToken 可以保证即使在异常情况下,这些操作也能被执行。
4. onceToken 的代码实现
以下是 onceToken 类的完整代码:
#ifndef UTIL_ONCETOKEN_H_
#define UTIL_ONCETOKEN_H_#include <functional>
#include <type_traits>namespace toolkit {class onceToken {
public:using task = std::function<void(void)>;template<typename FUNC>onceToken(const FUNC &onConstructed, task onDestructed = nullptr) {onConstructed();_onDestructed = std::move(onDestructed);}onceToken(std::nullptr_t, task onDestructed = nullptr) {_onDestructed = std::move(onDestructed);}~onceToken() {if (_onDestructed) {_onDestructed();}}private:onceToken() = delete;onceToken(const onceToken &) = delete