修复读取IMEI线程无法退出的bug

This commit is contained in:
cxh 2026-01-04 17:42:16 +08:00
parent 70d1ce151f
commit 8bc2a2e0fe
3 changed files with 74 additions and 24 deletions

View File

@ -2,6 +2,11 @@
#include "serial_port.h" #include "serial_port.h"
// 全局 IMEI读取成功后写入
extern std::string IMEI;
// 初始化 AT 串口(启动线程)
void init_serial_at(const std::string& device, int baudrate); void init_serial_at(const std::string& device, int baudrate);
extern std::string IMEI; // 停止 AT 串口停止线程join
void stop_serial_at();

View File

@ -86,6 +86,8 @@ int main()
// 停止 RecordManager 自动扫描线程 // 停止 RecordManager 自动扫描线程
if (g_record_manager) g_record_manager->stopAutoScan(); if (g_record_manager) g_record_manager->stopAutoScan();
stop_serial_at();
RTMPManager::stop_all(); RTMPManager::stop_all();
if (mqtt_thread.joinable()) if (mqtt_thread.joinable())

View File

@ -1,13 +1,20 @@
#include "serial_AT.hpp" #include "serial_AT.hpp"
#include <algorithm> #include <algorithm>
#include <atomic>
#include <chrono> #include <chrono>
#include <mutex> #include <mutex>
#include <sstream> #include <sstream>
#include <thread> #include <thread>
#include "logger.hpp"
#include "serial_port.h"
// ================== 全局 IMEI ================== // ================== 全局 IMEI ==================
std::string IMEI; // 一般 15 位 std::string IMEI;
// ================== 运行控制 ==================
static std::atomic<bool> serial_at_running{false};
// ================== AT 任务结构 ================== // ================== AT 任务结构 ==================
struct AtTask struct AtTask
@ -28,7 +35,9 @@ static std::vector<AtTask> at_tasks = {{"AT+GSN", 3, 0, {}}};
// ================== 发送线程 ================== // ================== 发送线程 ==================
static void serial_at_send_loop() static void serial_at_send_loop()
{ {
while (true) LOG_INFO("[serial_at] Sender thread started");
while (serial_at_running.load(std::memory_order_relaxed))
{ {
if (!serial_at || !serial_at->is_open()) if (!serial_at || !serial_at->is_open())
{ {
@ -37,32 +46,36 @@ static void serial_at_send_loop()
} }
auto now = std::chrono::steady_clock::now(); auto now = std::chrono::steady_clock::now();
std::lock_guard<std::mutex> lock(at_tasks_mutex);
for (auto it = at_tasks.begin(); it != at_tasks.end();)
{ {
auto& task = *it; std::lock_guard<std::mutex> lock(at_tasks_mutex);
if (task.sent_count >= task.max_retries) for (auto it = at_tasks.begin(); it != at_tasks.end();)
{ {
// 达到最大重试次数,直接移除 auto& task = *it;
it = at_tasks.erase(it);
continue;
}
if (task.last_sent.time_since_epoch().count() == 0 || if (task.sent_count >= task.max_retries)
std::chrono::duration_cast<std::chrono::seconds>(now - task.last_sent).count() >= 5) {
{ it = at_tasks.erase(it);
serial_at->send_data(task.cmd + "\r\n"); continue;
task.sent_count++; }
task.last_sent = now;
}
++it; if (task.last_sent.time_since_epoch().count() == 0 ||
std::chrono::duration_cast<std::chrono::seconds>(now - task.last_sent).count() >= 5)
{
serial_at->send_data(task.cmd + "\r\n");
task.sent_count++;
task.last_sent = now;
}
++it;
}
} }
std::this_thread::sleep_for(std::chrono::seconds(1)); std::this_thread::sleep_for(std::chrono::seconds(1));
} }
LOG_INFO("[serial_at] Sender thread exiting");
} }
// ================== 接收处理 ================== // ================== 接收处理 ==================
@ -77,13 +90,13 @@ static void handle_serial_at_data(const std::string& data)
line.erase(0, line.find_first_not_of(" \t\r\n")); line.erase(0, line.find_first_not_of(" \t\r\n"));
line.erase(line.find_last_not_of(" \t\r\n") + 1); line.erase(line.find_last_not_of(" \t\r\n") + 1);
// IMEI14~17 位纯数字(不同模组略有差异) // IMEI14~17 位纯数字
if (line.size() >= 14 && line.size() <= 17 && std::all_of(line.begin(), line.end(), ::isdigit)) if (line.size() >= 14 && line.size() <= 17 && std::all_of(line.begin(), line.end(), ::isdigit))
{ {
IMEI = line; IMEI = line;
LOG_INFO("[serial_at] IMEI = " + IMEI); LOG_INFO("[serial_at] IMEI = " + IMEI);
// 成功后清空任务,不再发送 AT // 成功后清空任务,不再发送
std::lock_guard<std::mutex> lock(at_tasks_mutex); std::lock_guard<std::mutex> lock(at_tasks_mutex);
at_tasks.clear(); at_tasks.clear();
return; return;
@ -91,14 +104,44 @@ static void handle_serial_at_data(const std::string& data)
} }
} }
// ================== 初始化接口 ================== // ================== 初始化 ==================
void init_serial_at(const std::string& device, int baudrate) void init_serial_at(const std::string& device, int baudrate)
{ {
serial_at = std::make_unique<SerialPort>("serial_at", device, baudrate, 5); if (serial_at_running.load())
{
LOG_WARN("[serial_at] Already running");
return;
}
serial_at_running.store(true, std::memory_order_relaxed);
serial_at = std::make_unique<SerialPort>("serial_at", device, baudrate, 5);
serial_at->set_receive_callback(handle_serial_at_data); serial_at->set_receive_callback(handle_serial_at_data);
serial_at->start(); serial_at->start();
serial_at_sender = std::thread(serial_at_send_loop); serial_at_sender = std::thread(serial_at_send_loop);
serial_at_sender.detach(); }
// ================== 停止 ==================
void stop_serial_at()
{
if (!serial_at_running.load()) return;
LOG_INFO("[serial_at] Stopping...");
serial_at_running.store(false, std::memory_order_relaxed);
if (serial_at)
{
serial_at->stop(); // 关闭串口,解除阻塞
}
if (serial_at_sender.joinable())
{
serial_at_sender.join();
}
serial_at.reset();
LOG_INFO("[serial_at] Stopped cleanly");
} }