first commit

This commit is contained in:
cxh 2025-09-10 12:49:41 +08:00
parent f080920590
commit b5b24b38e6

View File

@ -6,43 +6,29 @@
#include <thread> #include <thread>
#include <atomic> #include <atomic>
#include <csignal> #include <csignal>
#include <unistd.h> // write, STDOUT_FILENO
#include <chrono>
std::atomic<bool> g_running(true); std::atomic<bool> g_running(true);
// main.cpp - 修改signalHandler static void minimal_signal_handler(int signum)
void signalHandler(int signum)
{ {
static bool already_called = false; // 只做非常有限且 async-signal-safe 的操作
if (already_called) g_running.store(false, std::memory_order_relaxed);
return; const char msg[] = "[MAIN] Signal received, initiating shutdown...\n";
already_called = true; write(STDERR_FILENO, msg, sizeof(msg) - 1);
// 不要调用 LOG_*、malloc、std::string、mutex、exit 等
LOG_INFO("[MAIN] Received signal " + std::to_string(signum) + ", shutting down...");
g_running = false;
// 停止RTSP循环
RTSPManager::stop();
// 记录停止时间
auto start_time = std::chrono::steady_clock::now();
// 等待一段时间让线程退出
while (std::chrono::steady_clock::now() - start_time < std::chrono::seconds(3))
{
std::this_thread::sleep_for(std::chrono::milliseconds(100));
}
LOG_INFO("[MAIN] Force exiting after waiting for threads");
exit(1);
} }
int main() int main()
{ {
struct sigaction sigIntHandler; // 安装信号处理SIGINT 和 SIGTERM
sigIntHandler.sa_handler = signalHandler; struct sigaction sigAct{};
sigemptyset(&sigIntHandler.sa_mask); sigAct.sa_handler = minimal_signal_handler;
sigIntHandler.sa_flags = 0; sigemptyset(&sigAct.sa_mask);
sigaction(SIGINT, &sigIntHandler, NULL); sigAct.sa_flags = 0;
sigaction(SIGINT, &sigAct, nullptr);
sigaction(SIGTERM, &sigAct, nullptr);
signal(SIGPIPE, SIG_IGN); signal(SIGPIPE, SIG_IGN);
// 初始化日志文件 // 初始化日志文件
@ -59,31 +45,82 @@ int main()
return -1; return -1;
} }
// 线程退出标志,用于超时等待
std::atomic<bool> rtsp_thread_exited(false);
std::atomic<bool> mqtt_thread_exited(false);
// 先在主线程初始化 GStreamer // 先在主线程初始化 GStreamer
RTSPManager::init(); RTSPManager::init();
std::thread rtsp_thread([&]() std::thread rtsp_thread([&]()
{ RTSPManager::start(g_app_config.cameras); }); {
std::thread mqtt_thread(mqtt_client_thread_func); 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) while (g_running.load(std::memory_order_relaxed))
std::this_thread::sleep_for(std::chrono::milliseconds(200)); std::this_thread::sleep_for(std::chrono::milliseconds(200));
// 在main函数等待线程结束处添加日志 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.joinable())
{ {
LOG_INFO("[MAIN] Waiting for RTSP thread to finish..."); if (rtsp_thread_exited.load(std::memory_order_relaxed))
{
rtsp_thread.join(); rtsp_thread.join();
LOG_INFO("[MAIN] RTSP thread finished"); 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.joinable())
{ {
LOG_INFO("[MAIN] Waiting for MQTT thread to finish..."); if (mqtt_thread_exited.load(std::memory_order_relaxed))
{
mqtt_thread.join(); mqtt_thread.join();
LOG_INFO("[MAIN] MQTT thread finished"); 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."); LOG_INFO("[MAIN] Program exited cleanly.");
return 0; return 0;
} }