fix data race

This commit is contained in:
lnk
2025-12-11 15:07:54 +08:00
parent 7dbd4593fa
commit 2c48d7ae0a
5 changed files with 86 additions and 58 deletions

View File

@@ -46,9 +46,6 @@ extern int g_front_seg_index;
extern int g_front_seg_num; extern int g_front_seg_num;
extern unsigned int g_node_id; //前置程序类型(100-600) extern unsigned int g_node_id; //前置程序类型(100-600)
//初始化完成标识
extern int INITFLAG;
//线程阻塞计数 //线程阻塞计数
extern uint32_t g_ontime_blocked_times; extern uint32_t g_ontime_blocked_times;

View File

@@ -37,7 +37,27 @@
#include "rocketmq/MQClientException.h" #include "rocketmq/MQClientException.h"
#include "front.h" #include "front.h"
////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////命名空间
//lnk 20251211
namespace {
std::mutex g_streamMutex;
void safe_out_str(const std::string& s) {
std::lock_guard<std::mutex> lk(g_streamMutex);
std::cout << s << std::flush;
}
void safe_out_line(const std::string& s) {
std::lock_guard<std::mutex> lk(g_streamMutex);
std::cout << s << std::endl;
}
void safe_err_line(const std::string& s) {
std::lock_guard<std::mutex> lk(g_streamMutex);
std::cerr << s << std::endl;
}
}
using json = nlohmann::json; using json = nlohmann::json;
@@ -49,7 +69,7 @@ std::string FRONT_PATH;
//初始化标志 //初始化标志
int INITFLAG = 0; std::atomic<int> INITFLAG{0};
//前置标置 //前置标置
std::string subdir = "cloudfrontproc"; //子目录 std::string subdir = "cloudfrontproc"; //子目录
@@ -434,7 +454,7 @@ std::string get_parent_directory() {
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////主功能线程 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////主功能线程
void Front::FrontThread() { void Front::FrontThread() {
std::cout << "FrontThread::run() is called ...... \n"; safe_out_line("FrontThread::run() is called ...... \n");
try { try {
while (!m_bIsFrontThreadCancle) { while (!m_bIsFrontThreadCancle) {
@@ -445,9 +465,9 @@ void Front::FrontThread() {
std::this_thread::sleep_for(std::chrono::milliseconds(100)); std::this_thread::sleep_for(std::chrono::milliseconds(100));
} }
} catch (const std::exception& e) { } catch (const std::exception& e) {
std::cerr << "[FrontThread] Caught exception: " << e.what() << std::endl; safe_err_line(std::string("[FrontThread] Caught exception: ") + e.what());
} catch (...) { } catch (...) {
std::cerr << "[FrontThread] Caught unknown exception" << std::endl; safe_err_line("[FrontThread] Caught unknown exception");
} }
// 设置重启标志 // 设置重启标志
@@ -456,7 +476,7 @@ void Front::FrontThread() {
m_needRestartFrontThread = true; m_needRestartFrontThread = true;
} }
std::cout << "[FrontThread] exited, will be restarted by monitor\n"; safe_out_line("[FrontThread] exited, will be restarted by monitor\n");
} }
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////定时任务 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////定时任务
@@ -465,7 +485,7 @@ void Front::OnTimerThread()
{ {
try { try {
std::this_thread::sleep_for(std::chrono::milliseconds(1000)); std::this_thread::sleep_for(std::chrono::milliseconds(1000));
std::cout << "OnTimerThread::run() is called ...... \n"; safe_out_line("OnTimerThread::run() is called ...... \n");
int hbCounter = 0; // 心跳计数 int hbCounter = 0; // 心跳计数
int backupCounter = 0; // 备份计数(分钟用) int backupCounter = 0; // 备份计数(分钟用)
@@ -499,10 +519,10 @@ void Front::OnTimerThread()
const int todayYMD = local_ymd_today(); // YYYYMMDD本地时区 const int todayYMD = local_ymd_today(); // YYYYMMDD本地时区
if (todayYMD != s_lastCleanupYMD) { if (todayYMD != s_lastCleanupYMD) {
// 说明进入了新的一天:执行清理(删除前日及更早的未配对事件) // 说明进入了新的一天:执行清理(删除前日及更早的未配对事件)
std::cout << "[OnTimerThread] daily cleanup start, today=" << todayYMD << std::endl; safe_out_line("[OnTimerThread] daily cleanup start, today=" + std::to_string(todayYMD) + "\n");
cleanup_old_unpaired_qvvr_events(); // 调用清理内存的暂态事件 cleanup_old_unpaired_qvvr_events(); // 调用清理内存的暂态事件
s_lastCleanupYMD = todayYMD; s_lastCleanupYMD = todayYMD;
std::cout << "[OnTimerThread] daily cleanup done" << std::endl; safe_out_line("[OnTimerThread] daily cleanup done\n");
} }
} }
@@ -513,9 +533,9 @@ void Front::OnTimerThread()
std::this_thread::sleep_for(std::chrono::milliseconds(1000)); std::this_thread::sleep_for(std::chrono::milliseconds(1000));
} }
} catch (const std::exception& e) { } catch (const std::exception& e) {
std::cerr << "[OnTimerThread] Caught exception: " << e.what() << std::endl; safe_err_line(std::string("[OnTimerThread] Caught exception: ") + e.what());
} catch (...) { } catch (...) {
std::cerr << "[OnTimerThread] Caught unknown exception" << std::endl; safe_err_line("[OnTimerThread] Caught unknown exception");
} }
{ {
@@ -523,7 +543,7 @@ void Front::OnTimerThread()
m_needRestartTimerThread = true; m_needRestartTimerThread = true;
} }
std::cout << "[OnTimerThread] exited, will be restarted by monitor\n"; safe_out_line("[OnTimerThread] exited, will be restarted by monitor\n");
} }
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////消费者线程 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////消费者线程
@@ -556,37 +576,37 @@ void Front::mqconsumerThread()
std::string key = sub.topic + ":" + sub.tag; std::string key = sub.topic + ":" + sub.tag;
callbackMap.emplace(key, sub.callback); callbackMap.emplace(key, sub.callback);
m_mqConsumer->subscribe(sub.topic, sub.tag); m_mqConsumer->subscribe(sub.topic, sub.tag);
std::cout << "[mqconsumerThread] 已订阅 Topic=\"" << sub.topic << "\", Tag=\"" << sub.tag << "\"" << std::endl; safe_out_line("[mqconsumerThread] 已订阅 Topic=\"" + sub.topic + "\", Tag=\"" + sub.tag + "\"\n");
} }
m_listener = std::make_shared<rocketmq::SubscriberListener>(callbackMap); m_listener = std::make_shared<rocketmq::SubscriberListener>(callbackMap);
m_mqConsumer->registerMessageListener(m_listener.get()); m_mqConsumer->registerMessageListener(m_listener.get());
m_mqConsumer->start(); m_mqConsumer->start();
std::cout << "[mqconsumerThread] Consumer 已启动,等待消息..." << std::endl; safe_out_line("[mqconsumerThread] Consumer 已启动,等待消息...\n");
// ✳️ 保持线程不主动退出,由 RocketMQ 内部驱动执行回调 // ✳️ 保持线程不主动退出,由 RocketMQ 内部驱动执行回调
// 如果 RocketMQ 内部机制失败或意外退出线程,就走 catch // 如果 RocketMQ 内部机制失败或意外退出线程,就走 catch
} }
catch (const rocketmq::MQClientException& e) { catch (const rocketmq::MQClientException& e) {
std::cerr << "[mqconsumerThread] MQClientException: " << e.what() << std::endl; safe_err_line(std::string("[mqconsumerThread] MQClientException: ") + e.what());
std::lock_guard<std::mutex> lock(m_threadCheckMutex); std::lock_guard<std::mutex> lock(m_threadCheckMutex);
m_needRestartConsumerThread = true; m_needRestartConsumerThread = true;
return; return;
} catch (const std::exception& e) { } catch (const std::exception& e) {
std::cerr << "[mqconsumerThread] std::exception: " << e.what() << std::endl; safe_err_line(std::string("[mqconsumerThread] std::exception: ") + e.what());
std::lock_guard<std::mutex> lock(m_threadCheckMutex); std::lock_guard<std::mutex> lock(m_threadCheckMutex);
m_needRestartConsumerThread = true; m_needRestartConsumerThread = true;
return; return;
} catch (...) { } catch (...) {
std::cerr << "[mqconsumerThread] Unknown exception" << std::endl; safe_err_line("[mqconsumerThread] Unknown exception");
std::lock_guard<std::mutex> lock(m_threadCheckMutex); std::lock_guard<std::mutex> lock(m_threadCheckMutex);
m_needRestartConsumerThread = true; m_needRestartConsumerThread = true;
return; return;
} }
// 程序运行中,消费者会通过回调处理消息,线程保持存活即可 // 程序运行中,消费者会通过回调处理消息,线程保持存活即可
std::cout << "[mqconsumerThread] Consumer 线程正在运行,等待消息到达..." << std::endl; safe_out_line("[mqconsumerThread] Consumer 线程正在运行,等待消息到达...");
} }
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////生产者线程 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////生产者线程
@@ -596,7 +616,7 @@ void Front::mqproducerThread()
try { try {
// 1. 初始化生产者 // 1. 初始化生产者
InitializeProducer(m_producer); InitializeProducer(m_producer);
std::cout << "\n[mqproducerThread] is running ...... \n\n"; safe_out_line("\n[mqproducerThread] is running ...... \n\n");
uint32_t count = 0; uint32_t count = 0;
@@ -615,6 +635,7 @@ void Front::mqproducerThread()
} }
if (data_gotten) { if (data_gotten) {
{
auto now = std::chrono::system_clock::now(); auto now = std::chrono::system_clock::now();
auto ms_part = std::chrono::duration_cast<std::chrono::milliseconds>( auto ms_part = std::chrono::duration_cast<std::chrono::milliseconds>(
now.time_since_epoch()) % 1000; now.time_since_epoch()) % 1000;
@@ -624,40 +645,50 @@ void Front::mqproducerThread()
char timeStr[32]; char timeStr[32];
std::strftime(timeStr, sizeof(timeStr), "%Y-%m-%d %H:%M:%S", &tm_buf); std::strftime(timeStr, sizeof(timeStr), "%Y-%m-%d %H:%M:%S", &tm_buf);
std::cout << "BEGIN my_queue_send no." << count std::ostringstream oss;
oss << "BEGIN my_queue_send no." << count
<< " >>>> " << timeStr << " >>>> " << timeStr
<< "." << std::setw(3) << std::setfill('0') << ms_part.count() << "." << std::setw(3) << std::setfill('0') << ms_part.count();
<< std::endl;
// 线程安全输出
safe_out_line(oss.str());
}
// 调用实际发送 // 调用实际发送
my_rocketmq_send(data, m_producer); my_rocketmq_send(data, m_producer);
now = std::chrono::system_clock::now(); {
ms_part = std::chrono::duration_cast<std::chrono::milliseconds>( auto now = std::chrono::system_clock::now();
auto ms_part = std::chrono::duration_cast<std::chrono::milliseconds>(
now.time_since_epoch()) % 1000; now.time_since_epoch()) % 1000;
time_t_part = std::chrono::system_clock::to_time_t(now); auto time_t_part = std::chrono::system_clock::to_time_t(now);
std::tm tm_buf;
localtime_r(&time_t_part, &tm_buf); localtime_r(&time_t_part, &tm_buf);
char timeStr[32];
std::strftime(timeStr, sizeof(timeStr), "%Y-%m-%d %H:%M:%S", &tm_buf); std::strftime(timeStr, sizeof(timeStr), "%Y-%m-%d %H:%M:%S", &tm_buf);
std::cout << "END my_queue_send no." << count++ std::ostringstream oss;
<< " >>>> " << timeStr oss << "END my_queue_send no." << count
<< "." << std::setw(3) << std::setfill('0') << ms_part.count() << " <<<< " << timeStr
<< "\n\n"; << "." << std::setw(3) << std::setfill('0') << ms_part.count();
safe_out_line(oss.str());
}
} }
g_mqproducer_blocked_times = 0; g_mqproducer_blocked_times = 0;
std::this_thread::sleep_for(std::chrono::milliseconds(10)); std::this_thread::sleep_for(std::chrono::milliseconds(10));
} }
std::cout << "[mqproducerThread] 正常退出\n"; safe_out_line("[mqproducerThread] 正常退出\n");
} }
catch (const std::exception& e) { catch (const std::exception& e) {
std::cerr << "[mqproducerThread] std::exception: " << e.what() << std::endl; safe_err_line(std::string("[mqproducerThread] std::exception: ") + e.what());
std::lock_guard<std::mutex> lock(m_threadCheckMutex); std::lock_guard<std::mutex> lock(m_threadCheckMutex);
m_needRestartProducerThread = true; m_needRestartProducerThread = true;
} }
catch (...) { catch (...) {
std::cerr << "[mqproducerThread] unknown exception\n"; safe_err_line("[mqproducerThread] unknown exception\n");
std::lock_guard<std::mutex> lock(m_threadCheckMutex); std::lock_guard<std::mutex> lock(m_threadCheckMutex);
m_needRestartProducerThread = true; m_needRestartProducerThread = true;
} }
@@ -704,7 +735,7 @@ void* cloudfrontthread(void* arg) {
// 更新线程状态为运行中 // 更新线程状态为运行中
pthread_mutex_lock(&thread_info[index].lock); pthread_mutex_lock(&thread_info[index].lock);
printf("cloudfrontthread %d started\n", index); safe_out_line(std::string("cloudfrontthread") + std::to_string(index) + " started\n");
thread_info[index].state = THREAD_RUNNING; thread_info[index].state = THREAD_RUNNING;
pthread_mutex_unlock(&thread_info[index].lock); pthread_mutex_unlock(&thread_info[index].lock);
@@ -720,13 +751,13 @@ void* cloudfrontthread(void* arg) {
//路径获取 //路径获取
FRONT_PATH = get_parent_directory(); FRONT_PATH = get_parent_directory();
std::cout << "FRONT_PATH:" << FRONT_PATH << std::endl; safe_out_line("FRONT_PATH:" + FRONT_PATH + "\n");
//声明前置 //声明前置
std::unique_ptr<Front> FrontProcess; std::unique_ptr<Front> FrontProcess;
FrontProcess = make_unique<Front>(); FrontProcess = make_unique<Front>();
std::cout << "[Main] Program running in background.\n"; safe_out_line("[Main] Program running in background.\n");
// 5) 主线程保持后台运行 // 5) 主线程保持后台运行
while(running) { while(running) {
@@ -758,28 +789,28 @@ void* cloudfrontthread(void* arg) {
}*/ }*/
if (FrontProcess->m_needRestartFrontThread) { if (FrontProcess->m_needRestartFrontThread) {
std::cout << "[Monitor] Restarting FrontThread..." << std::endl; safe_out_line("[Monitor] Restarting FrontThread...\n");
FrontProcess->StopFrontThread(); FrontProcess->StopFrontThread();
FrontProcess->StartFrontThread(); FrontProcess->StartFrontThread();
FrontProcess->m_needRestartFrontThread = false; FrontProcess->m_needRestartFrontThread = false;
} }
if (FrontProcess->m_needRestartConsumerThread) { if (FrontProcess->m_needRestartConsumerThread) {
std::cout << "[Monitor] Restarting MQConsumerThread..." << std::endl; safe_out_line("[Monitor] Restarting MQConsumerThread...\n");
FrontProcess->StopMQConsumerThread(); FrontProcess->StopMQConsumerThread();
FrontProcess->StartMQConsumerThread(); FrontProcess->StartMQConsumerThread();
FrontProcess->m_needRestartConsumerThread = false; FrontProcess->m_needRestartConsumerThread = false;
} }
if (FrontProcess->m_needRestartProducerThread) { if (FrontProcess->m_needRestartProducerThread) {
std::cout << "[Monitor] Restarting MQProducerThread..." << std::endl; safe_out_line("[Monitor] Restarting MQProducerThread...\n");
FrontProcess->StopMQProducerThread(); FrontProcess->StopMQProducerThread();
FrontProcess->StartMQProducerThread(); FrontProcess->StartMQProducerThread();
FrontProcess->m_needRestartProducerThread = false; FrontProcess->m_needRestartProducerThread = false;
} }
if (FrontProcess->m_needRestartTimerThread) { if (FrontProcess->m_needRestartTimerThread) {
std::cout << "[Monitor] Restarting TimerThread..." << std::endl; safe_out_line("[Monitor] Restarting TimerThread...\n");
FrontProcess->StopTimerThread(); // 先停 FrontProcess->StopTimerThread(); // 先停
FrontProcess->StartTimerThread(); // 再启 FrontProcess->StartTimerThread(); // 再启
FrontProcess->m_needRestartTimerThread = false; FrontProcess->m_needRestartTimerThread = false;
@@ -792,7 +823,7 @@ void* cloudfrontthread(void* arg) {
// 退出前标记为 STOPPED方便监控线程判断并重启 // 退出前标记为 STOPPED方便监控线程判断并重启
pthread_mutex_lock(&thread_info[index].lock); pthread_mutex_lock(&thread_info[index].lock);
thread_info[index].state = THREAD_STOPPED; thread_info[index].state = THREAD_STOPPED;
printf("cloudfrontthread %d stopped\n", index); safe_out_line(std::string("cloudfrontthread ") + std::to_string(index) + " stopped\n");
pthread_mutex_unlock(&thread_info[index].lock); pthread_mutex_unlock(&thread_info[index].lock);
return nullptr; return nullptr;

View File

@@ -72,7 +72,7 @@ extern std::string FRONT_INST;
extern uint32_t g_mqproducer_blocked_times; extern uint32_t g_mqproducer_blocked_times;
//初始化标志 //初始化标志
extern int INITFLAG; extern std::atomic<int> INITFLAG;
//测试用的终端数组 //测试用的终端数组
extern std::vector<std::string> TESTARRAY; extern std::vector<std::string> TESTARRAY;

View File

@@ -49,7 +49,7 @@ extern std::list<std::string> errorList, warnList, normalList;
extern std::mutex errorListMutex, warnListMutex, normalListMutex; extern std::mutex errorListMutex, warnListMutex, normalListMutex;
extern int IED_COUNT; extern int IED_COUNT;
extern int INITFLAG; extern std::atomic<int> INITFLAG;
extern int g_front_seg_index; extern int g_front_seg_index;
extern std::string subdir; extern std::string subdir;

View File

@@ -34,7 +34,7 @@ typedef struct {
} thread_info_t; } thread_info_t;
#endif #endif
extern int INITFLAG;//̨<>˵ȳ<CBB5>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD><EFBFBD>ɱ<EFBFBD>־ extern std::atomic<int> INITFLAG;//̨<>˵ȳ<CBB5>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD><EFBFBD>ɱ<EFBFBD>־
//extern void cleanup_args(ThreadArgs* args); //extern void cleanup_args(ThreadArgs* args);
void init_daemon(void) void init_daemon(void)