zoukankan      html  css  js  c++  java
  • 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;
    }

    测试结果:

     

  • 相关阅读:
    OpenStack开发基础-oslo.config
    对象的封装
    Oracle动态显示日志
    Marching squares &amp; Marching cubes
    Keil5.15使用GCC编译器链接.a库文件
    数据结构习题之树
    HDU 5358(2015多校联合训练赛第六场1006) First One (区间合并+常数优化)
    使用URL在线语音合成
    企业怎样高速搭建大数据处理系统
    http://blog.sina.com.cn/s/blog_7caae74b0100zl17.html
  • 原文地址:https://www.cnblogs.com/iclk/p/3945245.html
Copyright © 2011-2022 走看看