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;
    }

    测试结果:

     

  • 相关阅读:
    矩阵快速幂模板
    Kuangbin带你飞 AC自动机
    Kuangbin 带你飞 KMP扩展KMP Manacher
    Kuangbin 带你飞 数位DP题解
    kuangbin 带你飞 数学基础
    Kuangbin 带你飞-基础计算几何专题 题解
    最大团问题
    头文件
    Codeforces 362E Petya and Pipes 费用流建图
    kuangbin带你飞 匹配问题 二分匹配 + 二分图多重匹配 + 二分图最大权匹配 + 一般图匹配带花树
  • 原文地址:https://www.cnblogs.com/iclk/p/3945245.html
Copyright © 2011-2022 走看看