Browse Source

为区域超员增加了锁,防止同时产生相同的告警事件

lixioayao 6 years ago
parent
commit
6e0e4a8f2b

+ 20 - 2
module_service/area_business_count_checker.cpp

@@ -41,6 +41,8 @@ void area_business_count_checker::on_load_his(const std::shared_ptr<area_hover>&
     on_enter(a,c,ptr);
 }
 //增加计数,并进行判断
+//多线程环境有可能同时产生相同的告警。
+//如果多个线程同一时间触发。
 void area_business_count_checker::on_enter(const std::shared_ptr<area_hover>&a,
                                            const std::shared_ptr<card_location_base>&c,std::shared_ptr<business_data>&ptr)
 {
@@ -57,12 +59,16 @@ void area_business_count_checker::on_enter(const std::shared_ptr<area_hover>&a,
         int aid=a->m_area->id();
 	    EVENT_TYPE ev = a->m_area->is_mine()?EVENT_TYPE::ET_OVER_COUNT_PERSON : EVENT_TYPE::ET_AREA_OVER_COUNT_PERSON ;
         if(pc>limit_val){
+            lock();
 		    event_tool::instance()->handle_event(OT_AREA,ev,aid,limit_val,pc,a->m_area->m_event_person_count=true,DT_NORMAL);
+            unlock();
 		    log_info("person_count_enter:%d,v_count:%d limit:%d",aid,pc,limit_val);
         }
         if(pc_>limit_val){
+            lock();
 		    event_tool::instance()->handle_event(OT_AREA,ev,aid,limit_val,pc_,a->m_area->m_event_person_show_count=true,DT_SPECIAL);
-		    log_info("person_count_enter_show:%d,v_count:%d limit:%d",aid,pc,limit_val);
+            unlock();
+		    log_info("person_count_enter_show:%d,v_count:%d limit:%d",aid,pc_,limit_val);
         }
 	}
 	else if (c->is_vehicle())
@@ -76,12 +82,16 @@ void area_business_count_checker::on_enter(const std::shared_ptr<area_hover>&a,
         int aid=a->m_area->id();
 		EVENT_TYPE ev = a->m_area->is_mine()?EVENT_TYPE::ET_OVER_COUNT_VEHICLE : EVENT_TYPE::ET_AREA_OVER_COUNT_VEHICLE ;
         if(vc>limit_val){
+            lock();
 		    event_tool::instance()->handle_event(OT_AREA,ev,aid,limit_val,vc,a->m_area->m_event_vehicle_count=true,DT_NORMAL);
+            unlock();
 		    log_info("vehicle_count_enter:%d,v_count:%d limit:%d",aid,vc,limit_val);
         }
         if(vc_>limit_val){
+            lock();
 		    event_tool::instance()->handle_event(OT_AREA,ev,aid,limit_val,vc_,a->m_area->m_event_vehicle_show_count=true,DT_SPECIAL);
-		    log_info("vehicle_count_enter_show:%d,v_count:%d limit:%d",aid,vc,limit_val);
+            unlock();
+		    log_info("vehicle_count_enter_show:%d,v_count:%d limit:%d",aid,vc_,limit_val);
         }
 	}
 }
@@ -107,11 +117,15 @@ void area_business_count_checker::on_leave(const std::shared_ptr<area_hover>&a,
         int aid=a->m_area->id();
 	    EVENT_TYPE ev = a->m_area->is_mine()?EVENT_TYPE::ET_OVER_COUNT_PERSON : EVENT_TYPE::ET_AREA_OVER_COUNT_PERSON ;
 		if(a->m_area->m_event_person_count&& pc <= limit_val){
+            lock();
 			event_tool::instance()->handle_event(OT_AREA,ev,aid,limit_val,pc,a->m_area->m_event_person_count=false,DT_NORMAL);
+            unlock();
 		    log_info("person_count_leave:%d,v_count:%d limit:%d",aid,pc,limit_val);
         }
 		if(a->m_area->m_event_person_show_count&& pc_ <= limit_val){
+            lock();
 			event_tool::instance()->handle_event(OT_AREA,ev,aid,limit_val,pc_,a->m_area->m_event_person_show_count=false,DT_SPECIAL);
+            unlock();
 		    log_info("person_count_leave_show:%d,v_count:%d limit:%d",aid,pc,limit_val);
         }
 	}
@@ -126,11 +140,15 @@ void area_business_count_checker::on_leave(const std::shared_ptr<area_hover>&a,
         int aid=a->m_area->id();
 		EVENT_TYPE ev = a->m_area->is_mine()?EVENT_TYPE::ET_OVER_COUNT_VEHICLE : EVENT_TYPE::ET_AREA_OVER_COUNT_VEHICLE ;
 		if(a->m_area->m_event_vehicle_count&& pc <= limit_val){
+            lock();
 			event_tool::instance()->handle_event(OT_AREA,ev,aid,limit_val,pc,a->m_area->m_event_vehicle_count=false,DT_NORMAL);
+            unlock();
 		    log_info("vehicle_count_leave:%d,v_count:%d limit:%d",aid,pc,limit_val);
         }
 		if(a->m_area->m_event_vehicle_show_count&& pc_ <= limit_val){
+            lock();
 			event_tool::instance()->handle_event(OT_AREA,ev,aid,limit_val,pc_,a->m_area->m_event_vehicle_show_count=false,DT_SPECIAL);
+            unlock();
 		    log_info("vehicle_count_leave_show:%d,v_count:%d limit:%d",aid,pc,limit_val);
         }
 	}

+ 20 - 0
module_service/area_business_count_checker.h

@@ -2,6 +2,7 @@
 #define _area_business_count_checker_hpp_
 
 #include "area_business.h"
+#include "atomic"
 
 /*
 	判断当前区域a中的人数是否超过设定人数,超过后告警
@@ -10,6 +11,10 @@
 */
 struct area_business_count_checker:area_business
 {
+    area_business_count_checker()
+    {
+        m_mutex=0;
+    }
 	//服务器重启加载数据
 	void on_load_his(const std::shared_ptr<area_hover>&a,const std::shared_ptr<card_location_base>&c,std::shared_ptr<business_data>&ptr);
 	//增加计数,并进行判断
@@ -17,6 +22,21 @@ struct area_business_count_checker:area_business
 	void on_hover(const std::shared_ptr<area_hover>&a,const std::shared_ptr<card_location_base>&c,std::shared_ptr<business_data> ptr);
 	//减少计数
 	void on_leave(const std::shared_ptr<area_hover>&a,const std::shared_ptr<card_location_base>&c,std::shared_ptr<business_data> ptr);
+private:
+	std::atomic<int> m_mutex;
+	void lock()
+	{
+		int expected=0;
+		while(!m_mutex.compare_exchange_strong(expected,1))
+			expected=0;
+		assert(m_mutex.load()==1);
+	}
+
+	void unlock()
+	{
+		m_mutex.store(0);
+	}
+
 };