// main.cpp #include "app_config.hpp" #include "rtsp_manager.hpp" #include "logger.hpp" #include "mqtt_client_wrapper.hpp" #include #include #include #include // write, STDOUT_FILENO #include std::atomic g_running(true); static void minimal_signal_handler(int signum) { // 只做非常有限且 async-signal-safe 的操作 g_running.store(false, std::memory_order_relaxed); const char msg[] = "[MAIN] Signal received, initiating shutdown...\n"; write(STDERR_FILENO, msg, sizeof(msg) - 1); // 不要调用 LOG_*、malloc、std::string、mutex、exit 等 } int main() { // 安装信号处理(SIGINT 和 SIGTERM) struct sigaction sigAct{}; sigAct.sa_handler = minimal_signal_handler; sigemptyset(&sigAct.sa_mask); sigAct.sa_flags = 0; sigaction(SIGINT, &sigAct, nullptr); sigaction(SIGTERM, &sigAct, nullptr); 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; } // 线程退出标志,用于超时等待 std::atomic rtsp_thread_exited(false); std::atomic mqtt_thread_exited(false); // 先在主线程初始化 GStreamer RTSPManager::init(); std::thread rtsp_thread; std::thread mqtt_thread; std::thread rtsp_thread([&]() { RTSPManager::start(g_app_config.cameras); rtsp_thread_exited.store(true, std::memory_order_relaxed); }); // std::thread mqtt_thread([&]() // { // mqtt_client_thread_func(); // mqtt_thread_exited.store(true, std::memory_order_relaxed); }); // 等待退出信号 while (g_running.load(std::memory_order_relaxed)) std::this_thread::sleep_for(std::chrono::milliseconds(200)); LOG_INFO("[MAIN] Shutdown requested, stopping services..."); // 等线程优雅退出:总等待时间 (可调整) const auto max_wait = std::chrono::seconds(5); const auto poll_interval = std::chrono::milliseconds(100); auto deadline = std::chrono::steady_clock::now() + max_wait; // 等 RTSP 线程退出 while (!rtsp_thread_exited.load(std::memory_order_relaxed) && std::chrono::steady_clock::now() < deadline) { std::this_thread::sleep_for(poll_interval); } if (rtsp_thread.joinable()) { if (rtsp_thread_exited.load(std::memory_order_relaxed)) { rtsp_thread.join(); LOG_INFO("[MAIN] RTSP thread finished and joined."); } else { LOG_WARN("[MAIN] RTSP thread did not exit within timeout."); } } // 等 MQTT 线程退出 deadline = std::chrono::steady_clock::now() + max_wait; while (!mqtt_thread_exited.load(std::memory_order_relaxed) && std::chrono::steady_clock::now() < deadline) { std::this_thread::sleep_for(poll_interval); } if (mqtt_thread.joinable()) { if (mqtt_thread_exited.load(std::memory_order_relaxed)) { mqtt_thread.join(); LOG_INFO("[MAIN] MQTT thread finished and joined."); } else { LOG_WARN("[MAIN] MQTT thread did not exit within timeout."); } } // 如果某些线程仍未退出,强制结束进程(不会跑全局析构) if ((rtsp_thread.joinable() && !rtsp_thread_exited.load(std::memory_order_relaxed)) || (mqtt_thread.joinable() && !mqtt_thread_exited.load(std::memory_order_relaxed))) { LOG_ERROR("[MAIN] Threads did not exit in time. Forcing immediate termination."); _exit(1); // 强制退出(不会调用 atexit handlers) } LOG_INFO("[MAIN] Program exited cleanly."); return 0; }