From b301a7193a2a53c57d70a4b20ee9cf9d0ebd4e80 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=A4=8F=E6=A5=9A?= <771730766@qq.com> Date: Wed, 8 Jan 2020 09:59:07 +0800 Subject: [PATCH] =?UTF-8?q?Created=20=E4=BB=A3=E7=A0=81=E7=AF=87=E4=B9=8Bo?= =?UTF-8?q?nceToken=20(markdown)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 代码篇之onceToken.md | 70 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) create mode 100644 代码篇之onceToken.md diff --git a/代码篇之onceToken.md b/代码篇之onceToken.md new file mode 100644 index 0000000..491cb2d --- /dev/null +++ b/代码篇之onceToken.md @@ -0,0 +1,70 @@ +ZLMediaKit里面大量用到了一个名叫`onceToken`对象, 很多小伙伴对这个工具类不明就里,下面我在此解释下其作用: +- 1、作为全局变量用,在程序加载时执行特定代码,例如生成默认配置文件: +```C++ +////////////HLS相关配置/////////// +namespace Hls { +#define HLS_FIELD "hls." +//HLS切片时长,单位秒 +const string kSegmentDuration = HLS_FIELD"segDur"; +//HLS切片个数 +const string kSegmentNum = HLS_FIELD"segNum"; +//HLS切片从m3u8文件中移除后,继续保留在磁盘上的个数 +const string kSegmentRetain = HLS_FIELD"segRetain"; +//HLS文件写缓存大小 +const string kFileBufSize = HLS_FIELD"fileBufSize"; +//录制文件路径 +const string kFilePath = HLS_FIELD"filePath"; + +onceToken token([](){ + mINI::Instance()[kSegmentDuration] = 2; + mINI::Instance()[kSegmentNum] = 3; + mINI::Instance()[kSegmentRetain] = 5; + mINI::Instance()[kFileBufSize] = 64 * 1024; + mINI::Instance()[kFilePath] = "./www"; +},nullptr); +} //namespace Hls +``` + +- 2、作为static变量,确保代码只执行一次: +```C++ +int64_t HttpSession::onRecvHeader(const char *header,uint64_t len) { + typedef void (HttpSession::*HttpCMDHandle)(int64_t &); + static unordered_map s_func_map; + static onceToken token([]() { + s_func_map.emplace("GET",&HttpSession::Handle_Req_GET); + s_func_map.emplace("POST",&HttpSession::Handle_Req_POST); + }, nullptr); + + //后续代码省略 +} +``` + +- 3、作为局部变量,确保函数退出前做一些清理工作,例如释放锁: +```C++ + template + bool emitEvent(const string &strEvent,ArgsType &&...args){ + onceToken token([&] { + //上锁,记录锁定线程id + _mtxListener.lock(); + if(_lock_depth++ == 0){ + _lock_thread = this_thread::get_id(); + } + }, [&]() { + //释放锁,取消锁定线程id + if(--_lock_depth == 0){ + _lock_thread = thread::id(); + if(_map_moved){ + //还原_mapListener + _map_moved = false; + _mapListener = std::move(_mapListenerTemp); + } + } + _mtxListener.unlock(); + }); + + //后续代码省略 + } + +``` + +- 4、这个对象取名源自pthread_once以及ios下的dispatch_once。