• ACE handle_timeout 事件重入


    多线程运行反应器事件时, 注意handle_timeout会重入,单独线程不存在下列问题!

    1. 一个timer事件

    // test_ace_timer.cpp : Defines the entry point for the console application.
    //
    #include "stdafx.h"
    #include "ace/Time_Value.h"
    #include "ace/Log_Msg.h"
    #include "ace/Synch.h"
    #include "ace/Reactor.h"
    #include "ace/Event_Handler.h"
    #include "ace/Dev_Poll_Reactor.h"
    #include "ace/Thread_Manager.h"
    #include <ace/Dev_Poll_Reactor.h>
    #include "ace/TP_Reactor.h"
    
    long timer10 = 0;
    long timer15 = 0;
    
    class Timer_Handler : public ACE_Event_Handler
    {
    public:
        virtual int handle_timeout(const ACE_Time_Value &current_time, 
            const void *act /* = 0 */)
        {
            const int *num = ACE_static_cast(const int*,act);
            
            ACE_DEBUG((LM_INFO, ACE_TEXT("time: %d  in  --------
    "),num));
            
            int n = 0 ;
            for (int i=0; i < 50000000; i++)
            {
                n++;
            }
            ACE_DEBUG((LM_INFO, ACE_TEXT("time: %d  out ###########
    "),num));
            return 0;
        }
    protected:
    private:
    };
    
    ACE_THR_FUNC_RETURN thread_func(void *arg) 
    {
        ACE_TRACE("thread_func(void *)");
    
        ACE_Reactor::instance()->run_reactor_event_loop();
        
        return 0;
    }
    
    int Start()
    {
        // Create a reactor from a tp reactor.
        ACE_TP_Reactor reactor_impl;
        ACE_Reactor reactor(&reactor_impl);
        ACE_Reactor::instance(&reactor);
    
        // Spawn some threads which run the reactor event loop(s)
        ACE_Thread_Manager::instance()->spawn_n(5,     thread_func, 0, THR_NEW_LWP | THR_JOINABLE | THR_SCHED_RR);
        //ACE_Thread_Manager::instance()->spawn_n(1,     thread_func, 0, THR_NEW_LWP | THR_JOINABLE | THR_SCHED_RR);
    
    
        Timer_Handler *timer = new Timer_Handler;
        
        ACE_Time_Value time_delay1(0, 10); //10ms
        ACE_Time_Value time_delay2(0, 15); //15ms
    
        timer10 = ACE_Reactor::instance()->schedule_timer(timer, (void *)&timer10, time_delay1, time_delay1);
    
        //timer15 = ACE_Reactor::instance()->schedule_timer(timer, (void *)&timer15, time_delay2, time_delay2);
        
        // Let the thread manager wait for all threads
        ACE_Thread_Manager::instance()->wait();
    
    
        return 0;
    }
    
    int ACE_TMAIN(int argc, ACE_TCHAR *argv[]) 
    {
        // Make sure we ignore SIGPIPE.
        
        Start();
    
    
        // Parse arguments.
        return 0;
    }

    测试结果: 

    time_out事件多次被调用, 此时可以改用一次性超时规避此问题,在启用timer任务时,handle_timeout分别改为调用下面这句。

     

    timer10 = ACE_Reactor::instance()->schedule_timer(timer, (void *)&timer10, time_delay1);

    2.多个timer事件

     每个都注册一次性timer, 下列代码handle_timeout会重入, 若是存在其他共享资源,则有问题。

     避免这样问题,如是多个timer, 可加锁处理。

    // test_ace_timer.cpp : Defines the entry point for the console application.
    //
    #include "stdafx.h"
    #include "ace/Time_Value.h"
    #include "ace/Log_Msg.h"
    #include "ace/Synch.h"
    #include "ace/Reactor.h"
    #include "ace/Event_Handler.h"
    #include "ace/Dev_Poll_Reactor.h"
    #include "ace/Thread_Manager.h"
    #include <ace/Dev_Poll_Reactor.h>
    #include "ace/TP_Reactor.h"
    
    class Timer_Handler;
    
    long timer10 = 0;
    long timer15 = 0;
    ACE_Time_Value time_delay1(0, 10);
    ACE_Time_Value time_delay2(0, 15);
    
    Timer_Handler *timer = NULL; 
    
    class Timer_Handler : public ACE_Event_Handler
    {
    public:
        virtual int handle_timeout(const ACE_Time_Value &current_time, 
            const void *act /* = 0 */)
        {
            const int *num = ACE_static_cast(const int*,act);
            
            ACE_DEBUG((LM_INFO, ACE_TEXT("time: %d  in  --------
    "),*num));
            
            int n = 0 ;
            for (int i=0; i < 50000000; i++)
            {
                n++;
            }
            ACE_DEBUG((LM_INFO, ACE_TEXT("time: %d  out ###########
    "),*num));
    
            if (*num == timer10)
            {
                timer10 = ACE_Reactor::instance()->schedule_timer(timer, (void *)&timer10, time_delay1);
            }
            else if(*num == timer15)
            {
                timer15 = ACE_Reactor::instance()->schedule_timer(timer, (void *)&timer15, time_delay2);
            }
    
            return 0;
        }
    protected:
    private:
    };
    
    ACE_THR_FUNC_RETURN thread_func(void *arg) 
    {
        ACE_TRACE("thread_func(void *)");
    
        ACE_Reactor::instance()->run_reactor_event_loop();
        
        return 0;
    }
    
    int Start()
    {
        // Create a reactor from a tp reactor.
        ACE_TP_Reactor reactor_impl;
        ACE_Reactor reactor(&reactor_impl);
        ACE_Reactor::instance(&reactor);
    
        // Spawn some threads which run the reactor event loop(s)
        ACE_Thread_Manager::instance()->spawn_n(5,     thread_func, 0, THR_NEW_LWP | THR_JOINABLE | THR_SCHED_RR);
        //ACE_Thread_Manager::instance()->spawn_n(1,     thread_func, 0, THR_NEW_LWP | THR_JOINABLE | THR_SCHED_RR);
    
    
        timer = new Timer_Handler;
    
        timer10 = ACE_Reactor::instance()->schedule_timer(timer, (void *)&timer10, time_delay1);
    
        timer15 = ACE_Reactor::instance()->schedule_timer(timer, (void *)&timer15, time_delay2);
        
        // Let the thread manager wait for all threads
        ACE_Thread_Manager::instance()->wait();
    
    
        return 0;
    }
    
    int ACE_TMAIN(int argc, ACE_TCHAR *argv[]) 
    {
        // Make sure we ignore SIGPIPE.
        
        Start();
    
    
        // Parse arguments.
        return 0;
    }

    测试结果:

     

  • 相关阅读:
    编译问题汇总
    IAP测试购买失败,Error Domain=SKErrorDomain Code=0 "无法连接到 iTunes Store"
    关于H5移动端调试的那些事
    关于JS中this指向的说明
    关于UIControl响应事件说明
    绝对独创---关于直播(推流-拉流-服务器搭建)
    关于直播
    关于公司视频播放由mp4格式向m3u8格式转换的学习
    关于UIView中的endEditing:的使用
    关于UITableViewCell左滑显示多个功能的实现
  • 原文地址:https://www.cnblogs.com/iclk/p/3945245.html
Copyright © 2020-2023  润新知