做网站卖什么东西好中国建设人才信息网

当前位置: 首页 > news >正文

做网站卖什么东西好,中国建设人才信息网,做网站公司哪里好,企业网络推广分析1 啰嗦一番背景 这么多年#xff0c;换着槽位做牛做马#xff0c;没有什么钱途 手艺仍然很潮#xff0c;唯有对于第一线的码农工作#xff0c;孜孜不倦#xff0c;其实没有啥进步#xff0c;就是在不断地重复#xff0c;刷熟练度#xff0c;和同期的老兄弟们#xf…1 啰嗦一番背景 这么多年换着槽位做牛做马没有什么钱途 手艺仍然很潮唯有对于第一线的码农工作孜孜不倦其实没有啥进步就是在不断地重复刷熟练度和同期的老兄弟们那是千万不要有比较的想法Q一把说各有各的活路。 业务线技术线管理线通通都无成就。 唯有在一亩三分地上辛勤耕耘有了点成绩聊以慰藉 拉回正题 当前部门的项目团队并非纯粹嵌入式开发偏向于ARM高性能芯片unbuntu模式中位机的模块代码加上UT code前前后后加起来11W行了正式代码估计就4W左右其他都工具或者UT。 UT的改善也是从加入部门后开始加速的算是起到一定带领作用新特性的merge同时也要满足行覆盖率(分支覆盖率没有硬性要求代码设计的够好少一些if else就OK。 目前软件中一个比较大的问题是组件间只有API接口一路开发下来各个组件的API调用互相交织解耦困难千辛万苦将UT覆盖刷到超80个点mock遍布带来的副作用是UT文件的.o超大。 编出来的执行文件超过1个多GWindows上跑GCC交叉编译会OOM只有VClinux 两个环境上的UT可以编出来。 其实陷入了瓶颈。 接下来进入新一轮新特性开发期老的架构已经到了差不多不得不优化的程度。 算是在当前团队的最后一个心愿吧这不解决方案除了在业务流程优化软件架构改进上主要就是SOLID原则需要引入轻量级线程间异步消息架构。 并非线程池单纯的异步消息事件定时器这三种基本的功能。 Java环境下这都不是事C环境下搜索了一遍没有现成的。 boost有异步消息架构和定时器简单的也玩过感觉上我们用起来有些门槛随着C新标准不断引入新特性新功能boost对于中小型代码反而没有特别吃香的感觉。 Nokia开源的一款 event machine牛逼是牛逼门槛也高代码行数都快抵得上我们当前的项目的一小半了弃疗。 开源的一些找来找去在简洁上差点意思。 另外线程间异步消息架构是几乎所有稍微大型的一点的软件的刚需。 关键的关键是没有现成的这一点不得不口出脏话tm什么年代了这玩意还需要敝帚自珍当个宝就不能分享出来让广大的农民工朋友有一个基本的参考或者可以鄙视的模版 要自己开发了回忆起了10多年前Dopra的FID/PID初始化消息框架的架构。 琢磨了一段时间开动。 2 简单介绍线程间异步消息框架的概念 如下的讲述懒得画图了到处都可以搜索到画出来也是知识垃圾。 a 异步消息很简单 1对1C message broker桥接 C b 事件为 1对N(0…:n)发布和订阅模型 P(publisher) event broker S(subscribers) c 定时器 不搞callback这一套和起临时线程异步任务没有太大区别 T(trigger) timer engine  user(handler) 上述三种全部共享一个handlerFID/PID框架中的MsgProc message broker event broker timer engine 归属到一个全局功能实例齐活。 基础的架构设计完毕后开始猛起要做一个一天赚1000妹币的男人混到最惨了有木有 圈里面看到有老哥们6月27号周四拿了最后一次加班夜宵岁月不饶人一个有生命力的团队必然是一个不断推陈出新的团队。 老司机呆长的不到一定层级慢慢就成为重点优化对象。当时也是年轻气盛13年拿了个杭研十佳程序员年底被领导平衡绩效C果断离了。 历程转了个大弯这不Dopra的一套消息架构真香试着东施效颦了。 3 和Dopra框架的一点区别 不出意外的必然有很大的区别咱这个是缩水版就开发了4天连蒙带猜 1 受限于个人水平怎么简单怎么来元编程玩不来羞愧。 2 也没有单独的消息内存管理那一套如果是大型项目视情况而言想要做好内存操作隔离那还是需要的memory sandbox概念也早就有了有需要就加上 消息也不用老式的 VOS_MsgHeader paylaod这一套来管理踩内存尾记忆尤深通通简化当前的项目并不需要多个coordinator之间搞起咱就是单体。 用最土的union来描述基本消息结构想要玩的开搞成container的话那还有很多备选比如同OS内部 IPCzmq消息protobuf封装想要怎么玩几乎都玩得起了现在。 3 Dopra的FID/PID还负责启动时初始化也可以参考RT-Thread一套初始化方式笔者其实也准备用上没有啥技术上的巧接口预留各位看官可以酌情自己添加。 当然得当然都是tm指针在管理内存修改上完全开放的。 10年了该忘的不该忘的差不多忘记伴随着年级增加的只有体重。 4 干货分享 声明 笔者也是受益于互联网各位看官下载源码后可自由分发和修改笔者天然放弃著作权有部分源码参考自github  cpptime/cpptime.h at master · eglimi/cpptime · GitHub。 笔者当前分享的是初稿只跑了几个UT case后续看情况待完善后会更新。 笔者相信当前的代码离商业级别应该有一些差距给大家带来的不便也敬请原谅就开发了4天中间还不断给各种杂事打断。 4.1 源代码目录 . ├── include │   ├── VOS_Def.h │   ├── VOS_IHandler.h │   ├── VOS_Interface.h │   └── private │   ├── VOS_InterfaceImpl.h │   ├── VOS_MsgQueue.h │   └── VOS_TimerImpl.h ├── src │   ├── VOS_IHandler.cpp │   ├── VOS_InterfaceImpl.cpp │   └── VOS_TimerImpl.cpp └── tst└── VOS_IHandler_test.cpp 4.2 头文件介绍 4.2.1 VOS_Def.h 该文件由用户定制有部分基础结构建议不要修改比如VosMessage这种比如消息基础结构消息IDtimer 类型event id以及对应的携带参数 #ifndef VOS_DEFH #define VOS_DEFH #include chrononamespace VOS {enum class VOS_MessageType {VOS_SYNC_MSG,VOS_TIMER,VOS_EVENT,VOS_BOTTOM 255 };enum class VOS_CompName {COMP_A 0,COMP_B 1,COMP_C 2,COMP_D 3,COMP_E 4,COMP_F 5,COMP_AR 6,COMP_RED 7,COMP_Bottom 8 // the last one, if you add new one,COMP_Bottom must increase };// user need define own EventID enum class VOS_EventID {SUB_SAHA_INIT_START 0,SUB_SAHA_INIT_READY 1,EVENT_SAHA_SOMETHING_OK,EVENT_SAHA_SOMETHING_FAIL};struct REP_ID_DATA {int programId;int assayNumber;int repIdx; };typedef union {REP_ID_DATA repData;int reserve_1; } VOSEventArg;enum class VOSTimerType {VOSTimerType_1,VOSTimerType_2,VOSTimerType_3,VOSTimerType_BOTTOM 255 };struct VOS_TIMER_MSG {VOSTimerType timerType; };/* message id VOS_ENV_XXX_REQ VOS_ENV_XXX_RESP /struct VOS_SYNC_MSG {int msgId;//add your own structure };struct VOS_EVENT_MSG {VOS_EventID eventId;VOSEventArg arg; };/** 消息中携带的结构可能多种多样要兼容各种结构在实现上难度太大 这里的轻量级消息结构基本元素为一段固定大小的内存块选用union结构* union结构有限制不同编译器可能不一样最好在基层结构中不要用用户自定义的构造函数* 可参看 https://learn.microsoft.com/zh-cn/cpp/cpp/unions?viewmsvc-170** union的一大特征在于一个Union类中的所有数据共享同一段内存。* 如果union类的成员包含自己的构造函数析构函数* 那么同一union类的成员在初始化时就有可能会执行不同的构造函数。* 这是无法预料的。所以我们在定义union类时要尽量避免成员变量是对象含有自己的构造函数* 子结构中最好不要包含自定义的一些类结构* 看下面 std::string 的报错* 注 如果当前的编译器支持C17以及以上的版本则用std::variant, 类型安全有保证也完全OK/ typedef union {VOS_SYNC_MSG xSyncMsg;VOS_TIMER_MSG xTimerMsg;VOS_EVENT_MSG xEventMsg;//std::string test; error C2280: VOS::VosMsgData::VosMsgData(void)”: 尝试引用已删除的函数 } VosMsgData;struct VosMessage {VosMessage(VOSMessageType msgType) :msgType(msgType){}VOSMessageType msgType;VosMsgData msgData_; };using timer_id std::size_t; using clock std::chrono::steady_clock; using timestamp std::chrono::time_pointclock;}#endif // VOS_DEF_H_4.2.2 VOS_Interface.h API 总入口单实例getInstance()方式调用笔者懒得private构造函数形式而已 设计上不完美这两个接口是内部框架调用的这里也暴露给了用户 virtual void VOS_RegisterEvent(VOS_EventID eventId, VOS_CompName name) 0;virtual void VOS_UnRegisterEvent(VOS_EventID eventId, VOS_CompName name) 0; #ifndef VOS_INTERFACEH #define VOS_INTERFACEH #include VOS_Def.h #include functionalnamespace VOS {class VOS_Interface { public:explicit VOS_Interface() default;virtual ~VOS_Interface() default;VOS_Interface(const VOS_Interface) delete;VOS_Interface(VOS_Interface) delete;VOS_Interface operator(const VOS_Interface) delete;VOS_Interface operator(VOS_Interface) delete;virtual void VOS_SendMsg(VOS_CompName name, VosMessage message) 0;virtual void VOS_PublishEvent(VOS_EventID eventId, const VOSEventArg arg) 0;virtual void VOS_RegisterEvent(VOS_EventID eventId, VOS_CompName name) 0;virtual void VOS_UnRegisterEvent(VOS_EventID eventId, VOS_CompName name) 0;virtual void VOS_RegisterInitCB(VOS_CompName name) 0;using MsgHandler std::functionvoid(const VosMessage msg);// warning: called by inner framework, user should not call thisvirtual void VOS_AddMsgHandler(VOS_CompName name, MsgHandler eh) 0;virtual void VOS_RemoveMsgHandler(VOS_CompName name) 0;virtual timer_id StartTimer(VOS_CompName name, VOSTimerType timerType, unsigned int expiredTime, bool isPeriodic false) 0;virtual bool Canceltimer(timer_id id) 0;static VOS_Interface getInstance();}; }#endif // VOS_INTERFACE_H_4.2.3 VOS_IHandler.h 每个需要处理消息的组件各自创建一个参数就是VOS_CompName name 用户基本上只要继承重载 virtual void handleMessage(const VosMessage msg) 0; 初始化完毕调用start() ,参看UT调用并没有明确限制可自行修改 void start(); 具体如下 #ifndef VOS_IHANDLERH #define VOS_IHANDLERH#include memory #include VOS_Def.hnamespace VOS {class VOS_IHandler { public:explicit VOS_IHandler(VOS_CompName name);virtual ~VOS_IHandler() default;VOS_IHandler() delete;VOS_IHandler(const VOS_IHandler) delete;VOS_IHandler(VOS_IHandler) delete;VOS_IHandler operator(const VOS_IHandler) delete;VOS_IHandler operator(VOS_IHandler) delete;void start();virtual void handleMessage(const VosMessage msg) 0;/ void VOSIHandler::handleMessage(const VosMessage msg){switch (msg.msgType){case VOS_MessageType::VOS_TIMER://do somethingbreak;case VOS_MessageType::VOS_BOTTOM:default:break;}}/protected:class Impl; std::sharedptrImpl pimpl; };} #endif / VOS_IHANDLERH */接下来是内部实现 4.2.4 VOS_InterfaceImpl.h 该内部头文件为VOS_Interface.h 接口的具体实现类 #ifndef VOS_INTERFACE_IMPLH #define VOS_INTERFACE_IMPLH #include memory #include map #include vector #include thread #include mutex #include VOS_Interface.h #include VOS_TimerImpl.hnamespace VOS { class VOS_InterfaceImpl : public VOS_Interface { public:VOS_InterfaceImpl();virtual ~VOS_InterfaceImpl();VOS_InterfaceImpl(const VOS_InterfaceImpl) delete;VOS_InterfaceImpl(VOS_InterfaceImpl) delete;VOS_InterfaceImpl operator(const VOS_InterfaceImpl) delete;VOS_InterfaceImpl operator(VOS_InterfaceImpl) delete;void VOS_SendMsg(VOS_CompName name, VosMessage message) override;void VOS_PublishEvent(VOS_EventID eventId, const VOSEventArg arg) override;void VOS_RegisterEvent(VOS_EventID eventId, VOS_CompName name) override;void VOS_UnRegisterEvent(VOS_EventID eventId, VOS_CompName name) override;void VOS_RegisterInitCB(VOS_CompName name) override;void VOS_AddMsgHandler(VOS_CompName name, MsgHandler eh) override;void VOS_RemoveMsgHandler(VOS_CompName name) override;timer_id StartTimer(VOS_CompName name, VOSTimerType timerType, unsigned int expiredms, bool isPeriodic) override;bool Canceltimer(timer_id id) override;void VOS_SendTimerMsg(VOS_CompName name, VOSTimerType timerType);private:void innerSendMsg(VOS_CompName name, VosMessage message);std::mapVOSCompName, MsgHandler handlers;std::mapVOS_EventID, std::vectorVOS_CompName eventmap;std::shared_ptrVOSTimer timers;std::mutex interfacelock;};}#endif // VOS_INTERFACE_IMPL_H_4.2.5 VOS_MsgQueue.h 为安全队列的基本封装有些冗余的代码部分原子变量操作时不完全规范大家可以用原生的atomic操作自行修改 #ifndef VOS_MSGQUEUEH #define VOS_MSGQUEUEH#include memory #include atomic #include queue #include functional #include iostream #include condition_variable#include VOS_Def.hnamespace VOS {using VOSQueueElementPtr std::unique_ptrVosMessage; using VOSQueueElements std::queueVOSQueueElementPtr;using SubscriberCb std::functionvoid(const VosMessage msg );class VOS_MsgQueue { public:explicit VOS_MsgQueue(){};~VOS_MsgQueue(){notify();};VOS_MsgQueue(const VOS_MsgQueue) delete;VOS_MsgQueue(VOS_MsgQueue) delete;VOS_MsgQueue operator(const VOS_MsgQueue) delete;VOS_MsgQueue operator(VOS_MsgQueue) delete;void addSubscriberCb(SubscriberCb Cb){subScriberCb Cb;}void sendMessage(VOSQueueElementPtr msg){std::unique_lockstd::mutex lck(VOSQueue_messagelock);// if queue size MAX_QUEUE_SIZE, that means VOS task might have some issue or might be blocked if(getRunningFlag() (VOSQueuemessages.size() MAX_QUEUE_SIZE)){VOSQueuemessages.push(std::move(msg));ready true;lck.unlock();notify();}}void handleMessage(){std::unique_lockstd::mutex lck(VOSQueue_messagelock);cv.wait(lck, this { return this-ready; });VOSQueueElements tmpVOSQueue;while(VOSQueuemessages.size()){tmpVOSQueue.push(std::move(VOSQueuemessages.front()));VOSQueuemessages.pop();}ready false;lck.unlock();while(tmpVOSQueue.size()){auto msg std::move(tmpVOSQueue.front());tmpVOSQueue.pop();//do somethingsubScriberCb(msg);}}int getQueueSize(){std::unique_lockstd::mutex lock(VOSQueue_messagelock);return static_castint(VOSQueuemessages.size());}void Stop(){{std::lock_guardstd::mutex lk{VOSQueue_messagelock};ready true;}// set atomic flag to true and notify event handler threadnotify();}void clear(){notify();}void notify(){cv.notify_all();}void clearQueue(){std::unique_lockstd::mutex lck(VOSQueue_messagelock);while(VOSQueuemessages.size()){VOSQueuemessages.pop();}interfaceRunningFlag_ false;}void setRunningFlag(bool flag){std::unique_lockstd::mutex lck(VOSQueue_messagelock);interfaceRunningFlag_ flag;}bool getRunningFlag(){return interfaceRunningFlag_;}private:const int MAX_QUEUE_SIZE 500;VOSQueueElements VOSQueuemessages;SubscriberCb subScriberCb;std::mutex VOSQueue_messagelock;std::conditionvariable cv;std::atomicbool interfaceRunningFlag false;bool ready false;std::atomicflag synFlag ATOMIC_FLAG_INIT; };}#endif // VOS_MSGQUEUE_H_4.2.6 VOS_TimerImpl.h 这个稍微复杂参考代码来自网页cpptime/cpptime.h at master · eglimi/cpptime · GitHub #ifndef VOS_TIMERIMPLH #define VOS_TIMERIMPLH#include VOS_Def.h #include algorithm #include chrono #include condition_variable #include functional #include memory #include mutex #include set #include stack #include thread #include vectornamespace VOS {using TimerSubscriberCb std::functionvoid(VOS_CompName name, VOSTimerType timerType);// Public types #if 0 using timer_id std::size_t; using handler_t std::functionvoid(timer_id); using clock std::chrono::steady_clock; using timestamp std::chrono::time_pointclock; #endif using duration std::chrono::milliseconds;// The event structure that holds the information about a timer. struct Event {timer_id id;timestamp start;duration period;VOS_CompName name;VOSTimerType timerType;bool valid;Event(): id(0), start(duration::zero()),period(duration::zero()),name(VOS_CompName::COMP_Bottom),timerType(VOSTimerType::VOSTimerType_BOTTOM),valid(false){}Event(timer_id id,timestamp start,duration period,VOS_CompName name,VOSTimerType timerType): id(id),start(start),period(period),name(name),timerType(timerType),valid(true){}Event(Event r) default;Event operator(Event ev) default;Event(const Event r) delete;Event operator(const Event r) delete; };// A time event structure that holds the next timeout and a reference to its // Event struct. struct Time_event {timestamp next;timer_id ref; };inline bool operator(const Time_event l, const Time_event r) {return l.next r.next; }class VOS_Timer {using scoped_m std::unique_lockstd::mutex;public:VOS_Timer();~VOS_Timer();// user should register first and then startvoid addSubscriberCb(TimerSubscriberCb Cb){subScriberCb Cb;}void start(){setRunningFlag(true);threadForTimer();}timer_id StartTimer(VOS_CompName name, VOSTimerType timerType, unsigned int expiredms, bool isPeriodic){return add(expiredms,name,timerType,isPeriodic? expiredms:0);}bool Canceltimer(timer_id id){return remove(id);}/** Add a new timer.** \param when The time at which the handler is invoked.* \param handler The callable that is invoked when the timer fires.* \param period The periodicity at which the timer fires. Only used for* periodic timers./timer_id add(const timestamp when, VOS_CompName name, VOSTimerType timerType,const duration period duration::zero()){scoped_m lock(m);timer_id id 0;// Add a new event. Prefer an existing and free id. If none is// available, add a new one.if (free_ids.empty()){id events.size();Event e(id, when, period, name, timerType);events.push_back(std::move(e));}else{id free_ids.top();free_ids.pop();Event e(id, when, period, name, timerType);events[id] std::move(e);}time_events.insert(Time_event{when, id});lock.unlock();cond.notify_all();return id;}/** Overloaded add function that uses a std::chrono::duration instead of* a time_point for the first timeout./template class Rep, class Periodinline timer_id add(const std::chrono::durationRep, Period when,VOS_CompName name, VOSTimerType timerType,const duration period duration::zero()){return add(clock::now() std::chrono::duration_caststd::chrono::milliseconds(when),name, timerType, period);}/** Overloaded add function that uses a uint64_t instead of a time_point* for the first timeout and the period./inline timer_id add(const uint64_t when, VOS_CompName name, VOSTimerType timerType,const uint64_t period 0){return add(duration(when), name, timerType, duration(period));}/** Removes the timer with the given id./bool remove(timer_id id){scoped_m lock(m);if (events.size() 0 || events.size() id){return false;}events[id].valid false;events[id].name VOS_CompName::COMP_Bottom;events[id].timerType VOSTimerType::VOSTimerType_BOTTOM;auto it std::find_if(time_events.begin(), time_events.end(), { return te.ref id; });if (it ! time_events.end()){free_ids.push(it-ref);time_events.erase(it);}lock.unlock();cond.notify_all();return true;}protected:TimerSubscriberCb subScriberCb;void setRunningFlag(bool flag);void release();void timerEngine();void threadForTimer();bool loopCondition(); private: const duration time_wait_step duration(100);//100ms// Thread and locking variables.std::mutex m;std::condition_variable cond;// The vector that holds all active events.std::vectorEvent events;// Sorted queue that has the next timeout at its top.std::multisetTime_event time_events;// A list of ids to be re-used. If possible, ids are used from this pool.std::stacktimer_id freeids;std::atomicbool runningFlag true;std::thread timerthread;};} // namespace VOS#endif / VOS_TIMERIMPLH */4.3 src下 cpp实现 4.3.1 VOS_IHandler.cpp #include iostream #include VOS_IHandler.h #include VOS_MsgQueue.h #include VOS_Interface.hnamespace VOS {class VOS_IHandler::Impl { public:explicit Impl(VOS_CompName name): Impl(name, std::make_sharedVOS_MsgQueue(), VOS_Interface::getInstance()){}Impl(VOS_CompName name,std::shared_ptrVOS_MsgQueue msgQueue,VOS_Interface vosinstance): name(name),msgQueue_(msgQueue),vosinstance(vos_instance){}~Impl(){release();}Impl() delete;Impl(const Impl) delete;Impl(Impl) delete;Impl operator(const Impl) delete;Impl operator(Impl) delete;void sendMsg(const VosMessage msg){auto element std::makeuniqueVosMessage(msg);msgQueue-sendMessage(std::move(element));}void start(SubscriberCb Cb){msgQueue-addSubscriberCb(std::forwardSubscriberCb(Cb));msgQueue-setRunningFlag(true);initAsyncMessageTask();vosinstance.VOSAddMsgHandler(name, {this-sendMsg(msg);});}protected:void initAsyncMessageTask();void release();void setRunningFlag(bool flag);bool loopCondition();void threadForEventHandler();void eventHandler();bool runningFlag_ false;std::thread event_handlerthread;VOSCompName name;std::shared_ptrVOSMsgQueue msgQueue;VOS_Interface vosinstance; };bool VOSIHandler::Impl::loopCondition() {return runningFlag; }void VOSIHandler::Impl::eventHandler() { while (loopCondition()){try{msgQueue-handleMessage();}catch(const std::exception e){return;}catch (…){return;}} }void VOS_IHandler::Impl::threadForEventHandler() {if(!event_handlerthread.joinable()){event_handlerthread std::thread(this{this-eventHandler();});} }void VOSIHandler::Impl::setRunningFlag(bool flag) {runningFlag flag; } void VOS_IHandler::Impl::initAsyncMessageTask() {setRunningFlag(true);threadForEventHandler(); }void VOS_IHandler::Impl::release() {vosinstance.VOSRemoveMsgHandler(name);setRunningFlag(false);if(event_handlerthread.joinable()){msgQueue_-Stop();event_handlerthread.join();} }VOS_IHandler::VOS_IHandler(VOSCompName name): pimpl( std::make_sharedVOS_IHandler::Impl(name) ) {}void VOSIHandler::start() {auto handler this{this-handleMessage(msg);};pimpl-start(handler); }} 4.3.2 VOS_InterfaceImpl.cpp #include VOS_InterfaceImpl.h #include algorithmnamespace VOS {VOS_InterfaceImpl::VOSInterfaceImpl(): timers(std::make_sharedVOSTimer()) {timers-addSubscriberCb(this{this-VOSSendTimerMsg(name, timerType);});timers-start(); } VOS_InterfaceImpl:: ~VOSInterfaceImpl() {timers.reset(); }void VOS_InterfaceImpl::VOS_AddMsgHandler(VOS_CompName name, MsgHandler eh) {if(!eh){return;}std::unique_lockstd::mutex lck(interfacelock);if (handlers.find(name) ! handlers.end()){handlers[name] std::move(eh);}else{handlers.insert(std::make_pair(name, std::forwardMsgHandler(eh)));}
}void VOS_InterfaceImpl::VOS_RemoveMsgHandler(VOS_CompName name) {std::unique_lockstd::mutex lck(interfacelock);auto handler {};if (handlers.find(name) ! handlers.end()){handlers_[name] std::move(handler);}}void VOS_InterfaceImpl::VOS_SendMsg(VOS_CompName name, VosMessage message) {std::unique_lockstd::mutex lck(interfacelock);innerSendMsg(name, message); }void VOS_InterfaceImpl::innerSendMsg(VOSCompName name, VosMessage message) {auto iter handlers.find(name);if(iter ! handlers.end()){iter-second(message);}//handlersname; }void VOS_InterfaceImpl::VOS_SendTimerMsg(VOS_CompName name, VOSTimerType timerType) {VosMessage message(VOS_MessageType::VOSTIMER);message.msgData.xTimerMsg.timerType timerType;VOS_SendMsg(name, message); }void VOS_InterfaceImpl::VOS_PublishEvent(VOS_EventID eventId, const VOSEventArg arg) {std::unique_lockstd::mutex lck(interfacelock);auto map_iter eventmap.find(eventId);if(map_iter ! eventmap.end()){std::for_each(map_iter-second.begin(), map_iter-second.end(), eventId, arg, this{VosMessage message(VOS_MessageType::VOSEVENT);message.msgData.xEventMsg.eventId static_castVOSEventID (eventId);message.msgData.xEventMsg.arg arg;this-innerSendMsg(name, message);});} }void VOS_InterfaceImpl::VOS_RegisterEvent(VOS_EventID eventId, VOS_CompName name) {std::unique_lockstd::mutex lck(interfacelock);auto map_iter eventmap.find(eventId);if(map_iter ! eventmap.end()){auto vec_iter std::find(map_iter-second.begin(), map_iter-second.end(), name);//already exist, returnif(vec_iter ! map_iter-second.end()){return;}// push back new oneelse{map_iter-second.push_back(name);}}else{eventmap[eventId].push_back(name);}return; }void VOS_InterfaceImpl::VOS_UnRegisterEvent(VOS_EventID eventId, VOS_CompName name) {std::unique_lockstd::mutex lck(interfacelock);auto map_iter eventmap.find(eventId);if(map_iter ! eventmap.end()){auto vec_iter std::find(map_iter-second.begin(), map_iter-second.end(), name);//already exist, returnif(vec_iter ! map_iter-second.end()){map_iter-second.erase(vec_iter);return;}}return; }void VOS_InterfaceImpl::VOS_RegisterInitCB(VOS_CompName name) {}timer_id VOS_InterfaceImpl::StartTimer(VOS_CompName name, VOSTimerType timerType, unsigned int expiredms, bool isPeriodic) {std::unique_lockstd::mutex lck(interfacelock);return timers_-StartTimer(name, timerType, expiredms, isPeriodic ); } #if 0 timer_id VOS_InterfaceImpl::StartTimer(VOS_CompName name, VOSTimerType timerType, const timestamp when, unsigned int interval) {std::unique_lockstd::mutex lck(interfacelock);return timers_-StartTimer(name, timerType, when, interval ); } #endif bool VOS_InterfaceImpl::Canceltimer(timer_id id) {std::unique_lockstd::mutex lck(interfacelock);return timers_-Canceltimer(id); }VOS_Interface VOS_Interface::getInstance() {static VOS_InterfaceImpl instance;return instance; }} 4..3.3 VOS_TimerImpl.cpp #include algorithm #include VOS_TimerImpl.hnamespace VOS {VOS_Timer::VOS_Timer() : m{}, cond{}, events{}, time_events{}, free_ids{} {}VOS_Timer:: ~VOS_Timer() {release(); }void VOSTimer::setRunningFlag(bool flag) {runningFlag flag; } void VOS_Timer::release() {setRunningFlag(false);if(timerthread.joinable()){cond.notify_all();timerthread.join();}events.clear();time_events.clear();while (!free_ids.empty()){free_ids.pop();} }bool VOSTimer::loopCondition() {return runningFlag; }void VOS_Timer::timerEngine() {int i 0; while (loopCondition()){scoped_m lock(m);if (time_events.empty()){// Wait for workcond.wait(lock);}else{Time_event te *time_events.begin();if (clock::now() te.next){// Remove time eventtime_events.erase(time_events.begin());// this is vital, remmber to addSubscriberCb firstlock.unlock();if(subScriberCb){subScriberCb(events[te.ref].name,events[te.ref].timerType);}lock.lock();if (events[te.ref].valid events[te.ref].period.count() 0){// The event is valid and a periodic timer.te.next events[te.ref].period;time_events.insert(te);}else{// The event is either no longer valid because it was// removed in the callback, or it is a one-shot timer.events[te.ref].valid false;events[te.ref].name VOS_CompName::COMP_Bottom;events[te.ref].timerType VOSTimerType::VOSTimerType_BOTTOM;free_ids.push(te.ref);}}else{//cond.wait_until(lock, te.next);auto duration_ms std::chrono::duration_caststd::chrono::milliseconds (te.next - std::chrono::steady_clock::now());auto wait_time duration_ms time_wait_step ? duration_ms : time_wait_step;cond.wait_for(lock, wait_time);}}}}void VOS_Timer::threadForTimer() {if(!timerthread.joinable()){timerthread std::thread(this{this-timerEngine();});} }} 简单党员测试代码(VC2022 上 google test的配置见之前文章) 4.4  UT 简单测试 VOS_IHandler_test.cpp #include iostream #include thread #include string#include VOS_IHandler.h #include VOSInterface.h#include gmock/gmock.h #include gtest/gtest.husing ::testing::; using ::testing::NiceMock; using ::testing::Return; using namespace testing;namespace VOS {class VOS_IHandlerWrapper : public VOS_IHandler { public:VOS_IHandlerWrapper(VOS_CompName name):VOSIHandler(name){}void handleMessage(const VosMessage msg){messagenum;switch (msg.msgType){case VOS_MessageType::VOS_SYNC_MSG:syncmsg msg.msgData.xSyncMsg;break;case VOS_MessageType::VOS_TIMER:timermsg msg.msgData.xTimerMsg;break;case VOS_MessageType::VOS_BOTTOM:break;case VOS_MessageType::VOS_EVENT:eventmsg msg.msgData.xEventMsg;break;default:break;}}void SleepForPeriod(int numberOfseconds){std::this_thread::sleep_for(std::chrono::seconds(numberOfseconds));}int messagenum 0;VOS_EVENT_MSG event_msg;VOS_SYNC_MSG sync_msg;VOS_TIMER_MSG timer_msg;};class VOS_IHandlerTest : public ::testing::Test {public:void SetUp() override{messageHandler_ar std::make_sharedVOS_IHandlerWrapper(VOS_CompName::COMP_AR);messageHandler_ar-start();messageHandler_red std::make_sharedVOS_IHandlerWrapper(VOS_CompName::COMP_RED);messageHandler_red-start();}std::shared_ptrVOS_IHandlerWrapper messageHandler_ar;std::shared_ptrVOS_IHandlerWrapper messageHandler_red;};TEST_F(VOS_IHandlerTest, VOS_SYNC_MSG_Process_OK) {VosMessage message(VOS_MessageType::VOS_SYNCMSG);message.msgData.xSyncMsg.reserve_1 999;VOS_Interface::getInstance().VOS_SendMsg(VOS_CompName::COMP_AR, message);messageHandler_ar-SleepForPeriod(2);if(messageHandler_ar-messagenum ! 0){EXPECT_EQ(messageHandler_ar-messagenum, 1);EXPECT_EQ(messageHandler_ar-sync_msg.reserve_1, 999);} }TEST_F(VOS_IHandlerTest, VOS_PublishEvent_OK) {VOS_Interface::getInstance().VOS_RegisterEvent( static_castVOS_EventID(5), VOS_CompName::COMP_AR);VOS_EventID eventId;VOSEventArg arg;arg.repData {1,2,3};VOS_Interface::getInstance().VOS_PublishEvent(static_castVOS_EventID(5), arg);messageHandler_ar-SleepForPeriod(2);if(messageHandler_ar-messagenum ! 0){EXPECT_EQ(messageHandler_ar-messagenum, 1);EXPECT_EQ(messageHandler_ar-event_msg.eventId, static_castVOS_EventID(5));EXPECT_EQ(messageHandler_ar-event_msg.arg.repData.programId, 1);EXPECT_EQ(messageHandler_ar-event_msg.arg.repData.assayNumber, 2);EXPECT_EQ(messageHandler_ar-event_msg.arg.repData.repIdx, 3);}VOS_Interface::getInstance().VOS_UnRegisterEvent( static_castVOS_EventID(5), VOS_CompName::COMP_AR); }TEST_F(VOS_IHandlerTest, VOS_TIMER_MSG_ONCE_TIMER_OK) {auto timer_id VOS_Interface::getInstance().StartTimer(VOS_CompName::COMP_AR, VOSTimerType::VOSTimerType_BOTTOM, 1000);messageHandler_ar-SleepForPeriod(2);if(messageHandler_ar-messagenum ! 0){EXPECT_EQ(messageHandler_ar-messagenum, 1);EXPECT_EQ(messageHandler_ar-timer_msg.timerType, VOSTimerType::VOSTimerType_BOTTOM);} }TEST_F(VOS_IHandlerTest, VOS_TIMER_MSG_PERIODIC_TIMER_OK) {auto timer_id VOS_Interface::getInstance().StartTimer(VOS_CompName::COMP_AR, VOSTimerType::VOSTimerType_BOTTOM, 300, true);messageHandler_ar-SleepForPeriod(1);if(messageHandler_ar-messagenum ! 0){EXPECT_EQ(messageHandler_ar-timer_msg.timerType, VOSTimerType::VOSTimerType_BOTTOM);}auto messagenum messageHandler_ar-messagenum;VOS_Interface::getInstance().Canceltimer(timer_id);messageHandler_ar-SleepForPeriod(1);EXPECT_EQ(messagenum, messageHandler_ar-messagenum); }}先写到这里无烟无酒无故事。 修改记录:  2024/07/02 开始UT 1 发现死锁VOS_PublishEvent-VOS_SendMsg  修改成  VOS_PublishEvent-innerSendMsg 2 timer等待最近的超时节点原先用的wait_until比如需要等待绝对时间2000ms的话这期间 其他地方调用CancelTimer就会由于被time线程lock住了造成pending状况直到wait_until超时返回因此粗暴的设置了一个100ms的最长等待周期用于释放锁。那么CancelTimer从理论上就有可能pending超过100ms这个在实时系统中是不可接受的只能用于一般性的对时延不太敏感的系统中。 这一点其实不太合心意后面再找找有没有更优秀的实现。