// main.cpp #include "app_config.hpp" #include "rtsp_manager.hpp" #include "logger.hpp" #include "mqtt_client_wrapper.hpp" #include #include #include std::atomic g_running(true); void signalHandler(int signum) { static bool already_called = false; if (already_called) return; already_called = true; LOG_INFO("[MAIN] Received signal " + std::to_string(signum) + ", shutting down..."); g_running = false; RTSPManager::stop(); // 停止 RTSP loop // 设置超时,防止无限等待 std::this_thread::sleep_for(std::chrono::milliseconds(500)); // 强制退出如果仍然卡住 if (signum == SIGINT) { exit(1); } } int main() { struct sigaction sigIntHandler; sigIntHandler.sa_handler = signalHandler; sigemptyset(&sigIntHandler.sa_mask); sigIntHandler.sa_flags = 0; sigaction(SIGINT, &sigIntHandler, NULL); signal(SIGPIPE, SIG_IGN); // 初始化日志文件 Logger::set_log_to_file(get_executable_dir_file_path("app.log")); try { // 从可执行文件所在目录读取配置文件 g_app_config = AppConfig::load_from_file(get_executable_dir_file_path("config.json")); } catch (const std::exception &e) { LOG_ERROR(std::string("Failed to load config: ") + e.what()); return -1; } // 先在主线程初始化 GStreamer RTSPManager::init(); std::thread rtsp_thread([&]() { RTSPManager::start(g_app_config.cameras); }); std::thread mqtt_thread(mqtt_client_thread_func); // 等待退出信号 while (g_running) std::this_thread::sleep_for(std::chrono::milliseconds(200)); // 在main函数等待线程结束处添加日志 if (rtsp_thread.joinable()) { LOG_INFO("[MAIN] Waiting for RTSP thread to finish..."); rtsp_thread.join(); LOG_INFO("[MAIN] RTSP thread finished"); } if (mqtt_thread.joinable()) { LOG_INFO("[MAIN] Waiting for MQTT thread to finish..."); mqtt_thread.join(); LOG_INFO("[MAIN] MQTT thread finished"); } LOG_INFO("[MAIN] Program exited cleanly."); return 0; }