瀏覽代碼

加入Manager模块,进行推理权限管理;加入设备内存监控,避免内存占满导致的系统卡死

lishengyin 3 年之前
父節點
當前提交
0a8c9ab362

+ 4 - 0
CMakeLists.txt

@@ -24,6 +24,8 @@ option(build_TCPClient "build module TCPClient" ON)
 option(build_recorder "build module recorder" ON)
 option(build_Cleaner "build modele Cleaner" ON)
 option(build_monitor "build modele monitor" ON)
+option(build_deviceState "build modele deviceState" ON)
+option(build_Manager "build modele Manager" ON)
 option(WITH_FFMPEG "with ffmpeg" ON)
 option(WITH_OPENCV "with opencv" ON)
 option(WITH_ZLMediaKit "with ZLMediaKit" OFF)
@@ -160,6 +162,8 @@ include_directories(${PROJECT_SOURCE_DIR}/modules/HttpClient/include/)
 include_directories(${PROJECT_SOURCE_DIR}/modules/recorder/include/)
 include_directories(${PROJECT_SOURCE_DIR}/modules/Cleaner/include/)
 include_directories(${PROJECT_SOURCE_DIR}/modules/monitor/include/)
+include_directories(${PROJECT_SOURCE_DIR}/modules/deviceState/include/)
+include_directories(${PROJECT_SOURCE_DIR}/modules/Manager/include/)
 
 include_directories(${ToolKit_Root})
 include_directories(${MediaKit_Root})

二進制
lib/libmodules.so


+ 8 - 0
modules/CMakeLists.txt

@@ -47,6 +47,14 @@ if(build_monitor)
   list(APPEND module_list monitor)
   install(DIRECTORY monitor/include/ DESTINATION include)
 endif()
+if(build_deviceState)
+  list(APPEND module_list deviceState)
+  install(DIRECTORY deviceState/include/ DESTINATION include)
+endif()
+if(build_Manager)
+  list(APPEND module_list Manager)
+  install(DIRECTORY Manager/include/ DESTINATION include)
+endif()
 
 if(HAVE_FFMPEG)
   include_directories(${FFMPEG_INCLUDE_DIR})

+ 113 - 0
modules/Manager/include/Manager.h

@@ -0,0 +1,113 @@
+/*
+ * @Description: 
+ * @Version: 1.0
+ * @Autor: lishengyin
+ * @Date: 2022-01-11 11:47:37
+ * @LastEditors: lishengyin
+ * @LastEditTime: 2022-01-11 14:40:35
+ */
+#pragma once
+
+#include <iostream>
+#include <iostream>
+#include <map>
+#include <time.h>
+#include <dirent.h>
+#include <time.h>
+#include <cstdlib>
+#include <dirent.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+#include "Util/logger.h"
+#include "Util/NoticeCenter.h"
+#include "Poller/EventPoller.h"
+#include "Player/PlayerProxy.h"
+#include "Rtmp/RtmpPusher.h"
+#include "Common/config.h"
+#include "Pusher/MediaPusher.h"
+#include "Extension/Frame.h"
+#include "Util/SqlPool.h"
+#include "Network/TcpClient.h"
+#include "Poller/Timer.h"
+#include "monitor.h"
+#include "Notices.h"
+#include "inference.h"
+#include "deviceState.h"
+
+
+using namespace toolkit;
+using namespace std;
+
+namespace MIVA{
+    class Manager
+    {
+    private:
+        int MemoryThreshold;
+        int TempThreshold;
+        
+    public:
+        Manager();
+        ~Manager();
+
+        /**
+         * @description: 创建实例
+         * @param {*}
+         * @return {*}
+         */        
+        static std::shared_ptr<Manager> CreateNew();
+
+        /**
+         * @description: 设置MemoryThreshold
+         * @param {int} MemoryThreshold
+         * @return {*}
+         */        
+        void setMemoryThreshold(int memoryThreshold);
+
+        /**
+         * @description: 设置温度阈值
+         * @param {int} TempThreshold
+         * @return {*}
+         */        
+        void setTempThreshold(int tempThreshold);
+
+        /**
+         * @description: 获取启动资格
+         * @param {*}
+         * @return {*}
+         */        
+        int32_t getStartPower();
+
+        /**
+         * @description: 获取停止的资格
+         * @param {*}
+         * @return {*}
+         */        
+        int32_t getStopPower();
+
+        /**
+         * @description: 获取清理的资格
+         * @param {*}
+         * @return {*}
+         */        
+        int32_t getClearPower();
+
+        /**
+         * @description: 获取同步数据的资格
+         * @param {*}
+         * @return {*}
+         */        
+        int32_t getSyncDataPower();
+
+        /**
+         * @description: 获取上层数据的资格
+         * @param {*}
+         * @return {*}
+         */        
+        int32_t getHostDataPower();
+        
+    public:
+        using Ptr = std::shared_ptr<Manager>;
+    };
+}

+ 111 - 0
modules/Manager/src/Manager.cpp

@@ -0,0 +1,111 @@
+/*
+ * @Description: 
+ * @Version: 1.0
+ * @Autor: lishengyin
+ * @Date: 2022-01-11 11:47:46
+ * @LastEditors: lishengyin
+ * @LastEditTime: 2022-01-11 14:51:57
+ */
+#include "Manager.h"
+
+
+namespace MIVA{
+
+    std::shared_ptr<Manager> m_manager = nullptr;
+    Manager::Manager(){
+    }
+
+    Manager::~Manager(){
+    }
+
+    /**
+     * @description: 创建实例
+     * @param {*}
+     * @return {*}
+     */    
+    std::shared_ptr<Manager> Manager::CreateNew(){
+        if(m_manager == nullptr) m_manager = std::make_shared<Manager>();
+        return m_manager;
+    }
+    
+    /**
+     * @description: 设置MemoryThreshold
+     * @param {int} MemoryThreshold
+     * @return {*}
+     */    
+    void Manager::setMemoryThreshold(int memoryThreshold){
+        this->MemoryThreshold  = memoryThreshold;
+    }
+
+    /**
+     * @description: 设置温度阈值
+     * @param {int} TempThreshold
+     * @return {*}
+     */    
+    void Manager::setTempThreshold(int tempThreshold){
+        this->TempThreshold = tempThreshold;
+    }
+
+    /**
+     * @description: 获得启动资格
+     * @param {*}
+     * @return {*}
+     */    
+    int32_t Manager::getStartPower(){
+        std::shared_ptr<Inference> Infer = Inference::CreateNew();
+        std::shared_ptr<deviceState> m_deviceState = deviceState::CreateNew();
+        int result = ERR;
+        if(Infer == nullptr) return result;
+        if(m_deviceState->getDeviceState() != OK) return result;
+        result = !Infer->Play ? OK : ERR;
+        // 内存余量较少,避免内存在未清理完全的时候启动,避免死机
+        if(m_deviceState->MemoryUsage < this-> MemoryThreshold) result = ERR;
+        return result;
+    }
+
+    /**
+     * @description: 获取停止资格
+     * @param {*}
+     * @return {*}
+     */    
+    int32_t Manager::getStopPower(){
+        std::shared_ptr<Inference> Infer = Inference::CreateNew();
+        if(Infer == nullptr) return ERR;
+        return Infer->Play ? OK : ERR;
+        return OK;
+    }
+
+    /**
+     * @description: 获取清理数据的资格
+     * @param {*}
+     * @return {*}
+     */    
+    int32_t Manager::getClearPower(){
+        
+        return OK;
+    }
+
+    /**
+     * @description: 获取同步数据的权力
+     * @param {*}
+     * @return {*}
+     */    
+    int32_t Manager::getSyncDataPower(){
+        std::shared_ptr<Inference> Infer = Inference::CreateNew();
+        if(Infer == nullptr) return ERR;
+        return !Infer->Play ? OK : ERR;
+    }
+
+    /**
+     * @description: 获取上层数据的资格
+     * @param {*}
+     * @return {*}
+     */    
+    int32_t Manager::getHostDataPower(){
+        std::shared_ptr<Inference> Infer = Inference::CreateNew();
+        if(Infer == nullptr) return ERR;
+        return !Infer->Play ? OK : ERR;
+    } 
+    
+}
+

+ 80 - 0
modules/deviceState/include/deviceState.h

@@ -0,0 +1,80 @@
+/*
+ * @Description: 
+ * @Version: 1.0
+ * @Autor: lishengyin
+ * @Date: 2022-01-11 10:44:52
+ * @LastEditors: lishengyin
+ * @LastEditTime: 2022-01-11 14:42:56
+ */
+#pragma once
+
+#include <iostream>
+#include <iostream>
+#include <map>
+#include <time.h>
+#include <dirent.h>
+#include <time.h>
+#include <cstdlib>
+#include <dirent.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+#include "Util/logger.h"
+#include "Util/NoticeCenter.h"
+#include "Poller/EventPoller.h"
+#include "Player/PlayerProxy.h"
+#include "Rtmp/RtmpPusher.h"
+#include "Common/config.h"
+#include "Pusher/MediaPusher.h"
+#include "Extension/Frame.h"
+#include "Util/SqlPool.h"
+#include "Network/TcpClient.h"
+#include "Poller/Timer.h"
+#include "monitor.h"
+#include <mutex>
+
+using namespace toolkit;
+using namespace std;
+
+namespace MIVA
+{
+    class deviceState
+    {
+    public:
+        using Ptr = std::shared_ptr<deviceState>;
+        int CpuUsage;
+        int GpuUsage;
+        int MemoryUsage;
+        int Temp;
+        int FdUsage;
+        
+    public:
+        deviceState();
+        ~deviceState();
+
+        /**
+         * @description: 创建实例
+         * @param {*}
+         * @return {*}
+         */  
+        static std::shared_ptr<deviceState> CreateNew();
+
+        /**
+         * @description: 获取设备数据
+         * @param {*}
+         * @return {*}
+         */        
+        int32_t getDeviceState();
+
+        /**
+         * @description: 同步设备数据
+         * @param {*}
+         * @return {*}
+         */        
+        int32_t SyncDeviceState(std::string& Ctime);
+    private:
+        mutex m_mutex;
+    };
+} // namespace MIVA
+

+ 68 - 0
modules/deviceState/src/deviceState.cpp

@@ -0,0 +1,68 @@
+/*
+ * @Description: 
+ * @Version: 1.0
+ * @Autor: lishengyin
+ * @Date: 2022-01-11 10:45:05
+ * @LastEditors: lishengyin
+ * @LastEditTime: 2022-01-11 14:43:10
+ */
+#include "deviceState.h"
+
+namespace MIVA
+{
+    std::shared_ptr<deviceState> m_deviceState = nullptr;
+    
+    deviceState::deviceState(){
+
+    }
+
+    deviceState::~deviceState(){
+
+    }
+
+    /**
+     * @description: 创建实例
+     * @param {*}
+     * @return {*}
+     */    
+    std::shared_ptr<deviceState> deviceState::CreateNew(){
+        if(m_deviceState == nullptr) m_deviceState = std::make_shared<deviceState>();
+        return m_deviceState;
+    }
+    
+    /**
+     * @description: 获取设备状态
+     * @param {*}
+     * @return {*}
+     */    
+    int32_t deviceState::getDeviceState(){
+        std::lock_guard<mutex> gurad(m_mutex);
+        std::shared_ptr<monitor> m_monitor = monitor::CreateNew();
+        if(m_monitor == nullptr) return -1;
+
+        this->CpuUsage = m_monitor->getCpuUsage();
+        this->GpuUsage = m_monitor->getGpuUsage();
+        this->MemoryUsage = m_monitor->getMemoryUsage();
+        this->Temp = m_monitor->getTemp();
+        this->FdUsage = m_monitor->getFdUsage();
+        
+        return 0;
+    }
+
+    /**
+     * @description: 同步设备数据
+     * @param {*}
+     * @return {*}
+     */    
+    int32_t deviceState::SyncDeviceState(std::string& Ctime){
+        std::lock_guard<mutex> gurad(m_mutex);
+        vector<vector<string>> sqlRet;
+
+        SqlWriter sqlUpdate_DeviceState("UPDATE MIVA_DB.DeviceState SET CpuUsage='?',GpuUsage='?',MemoryUsage='?',Temp='?',FdUsage='?',updateTime='?'");
+        sqlUpdate_DeviceState << this->CpuUsage << this->GpuUsage  << this->MemoryUsage << this->Temp << this->FdUsage  << Ctime << sqlRet;
+        
+        return 0;
+    }   
+} // namespace MIVA
+
+

+ 7 - 1
modules/inference/include/inference.h

@@ -4,7 +4,7 @@
  * @Autor: lishengyin
  * @Date: 2021-10-13 09:37:51
  * @LastEditors: lishengyin
- * @LastEditTime: 2022-01-06 15:15:22
+ * @LastEditTime: 2022-01-11 13:54:08
  */
 #pragma once
 #include <iostream>
@@ -85,6 +85,12 @@ namespace MIVA{
         Inference();
         ~Inference();
     public:
+        /**
+         * @description: 创建实例
+         * @param {*}
+         * @return {*}
+         */        
+        static std::shared_ptr<Inference> CreateNew();
 
         /**
          * @description: 推理模块初始化

+ 15 - 2
modules/inference/src/inference.cpp

@@ -4,7 +4,7 @@
  * @Autor: lishengyin
  * @Date: 2021-10-13 09:35:37
  * @LastEditors: lishengyin
- * @LastEditTime: 2022-01-07 09:52:33
+ * @LastEditTime: 2022-01-11 15:22:21
  */
 #include "inference.h"
 
@@ -57,7 +57,7 @@ map<string, map<int, queue<std::shared_ptr<cv::Mat>>>> m_frames;
 
 namespace MIVA{
     ThreadPool pool(4,ThreadPool::PRIORITY_HIGHEST, false);
-
+    std::shared_ptr<Inference> m_Inference = nullptr;
     Inference::Inference()
     {
         
@@ -85,6 +85,17 @@ namespace MIVA{
 
         this->m_InferInfo = NULL;
     } 
+
+    /**
+     * @description: 创建实例
+     * @param {*}
+     * @return {*}
+     */    
+    std::shared_ptr<Inference> Inference::CreateNew(){
+        if(m_Inference == nullptr) m_Inference = std::make_shared<Inference>();
+        return m_Inference;
+    }
+
     /**
      * @description: 推理模块初始化
      * @param {vector<DataSource>} DataList 数据源集合
@@ -555,8 +566,10 @@ namespace MIVA{
                     for(int column = 0; column < columns; column++){
                         if(column == 0){
                             img = source->second.front();
+                            if(img == nullptr) continue;
                             source->second.pop();
                         }else{
+                            if(source->second.front() == nullptr) continue;
                             hconcat(*img,*(source->second.front()),*img);
                             source->second.pop();
                         }

+ 1 - 8
modules/monitor/include/monitor.h

@@ -4,7 +4,7 @@
  * @Autor: lishengyin
  * @Date: 2022-01-10 15:01:15
  * @LastEditors: lishengyin
- * @LastEditTime: 2022-01-10 16:00:35
+ * @LastEditTime: 2022-01-11 11:12:08
  */
 #pragma once
 
@@ -53,13 +53,6 @@ namespace MIVA
         static std::shared_ptr<monitor> CreateNew();
         
         /**
-         * @description: 初始化
-         * @param {*}
-         * @return {*}
-         */        
-        int32_t Init();
-
-        /**
          * @description: 释放资源
          * @param {*}
          * @return {*}

+ 4 - 14
modules/monitor/src/monitor.cpp

@@ -4,7 +4,7 @@
  * @Autor: lishengyin
  * @Date: 2022-01-10 15:01:23
  * @LastEditors: lishengyin
- * @LastEditTime: 2022-01-10 16:06:25
+ * @LastEditTime: 2022-01-11 11:11:53
  */
 #include <monitor.h>
 
@@ -18,19 +18,7 @@ namespace MIVA
     monitor::~monitor(){
         this->Destory();
     }
-
-    /**
-     * @description: 初始化
-     * @param {*}
-     * @return {*}
-     */    
-    int32_t monitor::Init(){
-        this->file = fopen("/proc/meminfo","r");
-        if(this->file == nullptr) return -1;
-
-        return 0;
-    } 
-
+    
     /**
      * @description: 释放
      * @param {*}
@@ -56,6 +44,7 @@ namespace MIVA
      * @return {*}
      */    
     int32_t monitor::getMemoryUsage(){
+        this->file = fopen("/proc/meminfo","r");
         int32_t MemoryUsage = 0;
         char keyword[20];
         char valuech[20];
@@ -65,6 +54,7 @@ namespace MIVA
         fscanf(file,"MemFree: %s kB\n",valuech);
         fscanf(file,"MemAvailable: %s kB\n",valuech);
         MemoryUsage=atol(valuech)/1000;
+        if(this->file != nullptr) fclose(this->file);
         return MemoryUsage;
     }
 

+ 4 - 1
modules/recorder/src/recorder.cpp

@@ -53,7 +53,10 @@ namespace MIVA
             writer.fileName = fileName;
             this->videoWriters[Pid] = writer;
         }
-        if(outType) this->videoWriters[Pid].videoWriter->write(frame);
+        if(outType){
+            if(this->videoWriters[Pid].videoWriter != nullptr)
+                this->videoWriters[Pid].videoWriter->write(frame);
+        } 
     }
 
     /**

+ 13 - 1
modules/userApp/include/user_app.h

@@ -4,7 +4,7 @@
  * @Autor: lishengyin
  * @Date: 2021-10-13 09:41:50
  * @LastEditors: lishengyin
- * @LastEditTime: 2022-01-10 08:42:37
+ * @LastEditTime: 2022-01-11 12:34:12
  */
 #pragma once
 
@@ -53,6 +53,8 @@
 #include "recorder.h"
 #include "Cleaner.h"
 #include "monitor.h"
+#include "deviceState.h"
+#include "Manager.h"
 #include <httplib.h>
 
 using namespace toolkit;
@@ -171,6 +173,7 @@ namespace MIVA
         std::string port;
 
         int device_id;
+        int MemoryThreshold = 1024;
         bool play = false;
         bool start = true;
         bool enable = true;
@@ -181,6 +184,8 @@ namespace MIVA
         std::shared_ptr<recorder> m_recorder = nullptr;
         std::shared_ptr<Cleaner> m_Cleaner = nullptr;
         std::shared_ptr<monitor> m_monitor = nullptr;
+        deviceState::Ptr m_deviceState = nullptr;
+        Manager::Ptr m_manager = nullptr;
 
         Socket::Ptr m_udpClient = NULL;
 
@@ -283,5 +288,12 @@ namespace MIVA
          * @return {*}
          */    
         void MonitorData();
+
+        /**
+         * @description: 清理内除
+         * @param {*}
+         * @return {*}
+         */        
+        int32_t ClearMemory();
     };
 }

+ 33 - 15
modules/userApp/src/user_app.cpp

@@ -4,7 +4,7 @@
  * @Autor: lishengyin
  * @Date: 2021-10-13 09:35:42
  * @LastEditors: lishengyin
- * @LastEditTime: 2022-01-10 10:28:43
+ * @LastEditTime: 2022-01-11 14:54:04
  */
 #include "user_app.h"
 
@@ -32,6 +32,7 @@ namespace MIVA
     UserApp::~UserApp(){
         Destroy();
     }
+
     /**
      * @description: 初始化
      * @param {string} appName
@@ -93,9 +94,11 @@ namespace MIVA
         this->m_recorder = recorder::CreateNew();
         this->m_Cleaner = Cleaner::CreateNew();
         this->m_monitor = monitor::CreateNew();
+        this->m_deviceState = deviceState::CreateNew();
+        this->m_manager = Manager::CreateNew();
 
         // 查询基础配置
-        SqlWriter sqlSelectConfig("SELECT account,outType,outPath,outEnable,ClearType,recordMax,validTime FROM MIVA_DB.`MivaConfig`");
+        SqlWriter sqlSelectConfig("SELECT account,outType,outPath,outEnable,ClearType,recordMax,validTime,MemoryThreshold,TempThreshold FROM MIVA_DB.`MivaConfig`");
         sqlSelectConfig << sqlRet;
         for(auto &line : sqlRet)
         {
@@ -106,6 +109,8 @@ namespace MIVA
             this->m_Cleaner->ClearType = std::atoi(line[4].c_str());
             this->m_Cleaner->recordMax = std::atoi(line[5].c_str());
             this->m_Cleaner->validTime = std::atoi(line[6].c_str());
+            this->m_manager->setMemoryThreshold(std::atoi(line[7].c_str()));
+            this->m_manager->setTempThreshold(std::atoi(line[8].c_str()));
         }
 
         // 链接Netty后端
@@ -132,7 +137,7 @@ namespace MIVA
         this->m_InferInfo = InferInfo::CreateNew();
     
         // 初始化Deepstream
-        m_Infer = std::make_shared<Inference>();
+        m_Infer = Inference::CreateNew();
 
         if(m_Infer == NULL){
             ErrorL << "Inference module creation failed!";
@@ -160,7 +165,6 @@ namespace MIVA
             InfoL << "The stream to be played is not found, please add it in the background.";
         }
 
- 
         // 监听推理广播
         NoticeCenter::Instance().addListener(0,NOTICE_INFER,
                 [&](int Source_id, int num){
@@ -246,7 +250,7 @@ namespace MIVA
         this->m_timer3 = std::make_shared<Timer>(3.0f,[&](){
             if(this->m_httpClient->alive()){
                 // 获取数据
-                if(this->m_Infer->Play == false) this->GetNettyDatas();
+                if(this->m_manager->getHostDataPower() == OK) this->GetNettyDatas();
             }else{  // 未获取到Token
                 if(this->m_httpClient->LoginNetty() != OK){
                     ErrorL << "登录Netty失败" << endl;
@@ -258,7 +262,7 @@ namespace MIVA
         // 定时监控数据变化
         this->m_timer4 = std::make_shared<Timer>(3.0f,[&](){
             // 监听数据
-            if(this->m_Infer->Play == false) this->MonitorData();
+            if(this->m_manager->getSyncDataPower() == OK) this->MonitorData();
             return true;
         },nullptr);
 
@@ -295,7 +299,7 @@ namespace MIVA
      */    
     void UserApp::ListenInferPer()
     {
-        if(this->m_Infer->Play == true){
+        if(this->m_manager->getStopPower() == OK){
              // 推理结束发布InferData事件
             this->ListenInferData();
             this->m_Infer->Recorder();
@@ -466,7 +470,6 @@ namespace MIVA
         // std::string json;
         // memcpy((uint8_t *)(&json), (uint8_t *)(pBuf->data()), pBuf->size());
         
-
     }
 
     /**
@@ -508,8 +511,8 @@ namespace MIVA
             if((serverResultMag.DoorFlag & 0x80))
             {  
                 // 广播收到关门的信号
-                if(this->m_Infer->Play == false) this->ListenClosed();
-                else WarnL << "推理未结束" << endl;
+                if(this->m_manager->getStartPower() == OK) this->ListenClosed();
+                else WarnL << "推理未结束或内存所剩不足" << endl;
             }
         }
     }
@@ -555,10 +558,13 @@ namespace MIVA
         vector<DataSource>::iterator iter;
         char ctime[80];
         getDataTime(ctime);
-        SqlWriter sqlUpdate_DeviceState("UPDATE MIVA_DB.DeviceState SET CpuUsage='?',GpuUsage='?',MemoryUsage='?',Temp='?',FdUsage='?',updateTime='?'");
-        sqlUpdate_DeviceState << this->m_monitor->getCpuUsage() << this->m_monitor->getGpuUsage()  << this->m_monitor->getMemoryUsage() << this->m_monitor->getTemp() << this->m_monitor->getFdUsage() << ctime << sqlRet;
+        std::string Ctime = ctime;
 
-        SqlWriter sqlSelectConfig("SELECT account,outType,outPath,outEnable,ClearType,recordMax,validTime FROM MIVA_DB.`MivaConfig`");
+        // 设备数据
+        this->m_deviceState->getDeviceState();
+        this->m_deviceState->SyncDeviceState(Ctime);
+        
+        SqlWriter sqlSelectConfig("SELECT account,outType,outPath,outEnable,ClearType,recordMax,validTime,MemoryThreshold,TempThreshold FROM MIVA_DB.`MivaConfig`");
         sqlSelectConfig << sqlRet;
         for(auto &line : sqlRet)
         {
@@ -569,6 +575,8 @@ namespace MIVA
             this->m_Cleaner->ClearType = std::atoi(line[4].c_str());
             this->m_Cleaner->recordMax = std::atoi(line[5].c_str());
             this->m_Cleaner->validTime = std::atoi(line[6].c_str());
+            this->m_manager->setMemoryThreshold(std::atoi(line[7].c_str()));
+            this->m_manager->setTempThreshold(std::atoi(line[8].c_str()));
         }
         
         if(this->m_Infer->enable == false || this->m_InferInfo->DataSources.empty()){
@@ -658,7 +666,7 @@ namespace MIVA
             this->m_InferInfo->DataSources.clear();
         }        
     }
-    
+
     /**
      * @description: 赋值struct sockaddr
      * @param {sockaddr} *out
@@ -850,7 +858,7 @@ namespace MIVA
         }else{
             ErrorL << "SystemConfig 未查询到数据" << endl;
         }
-        
+
         // 解析
         if(!CrowdednessTimeConfigs.empty()){
             char ctime[80];
@@ -873,4 +881,14 @@ namespace MIVA
         }
         return grade;
     }
+
+    /**
+     * @description: 清理内存
+     * @param {*}
+     * @return {*}
+     */    
+    int32_t UserApp::ClearMemory(){
+
+        return 0;
+    }   
 }

二進制
source/bin/main