当多线程运行反应器事件时, 注意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 = ;
long timer15 = ; 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 --------\n"),num)); int n = ;
for (int i=; i < ; i++)
{
n++;
}
ACE_DEBUG((LM_INFO, ACE_TEXT("time: %d out ###########\n"),num));
return ;
}
protected:
private:
}; ACE_THR_FUNC_RETURN thread_func(void *arg)
{
ACE_TRACE("thread_func(void *)"); ACE_Reactor::instance()->run_reactor_event_loop(); return ;
} 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(, thread_func, , 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(, ); //10ms
ACE_Time_Value time_delay2(, ); //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 ;
} int ACE_TMAIN(int argc, ACE_TCHAR *argv[])
{
// Make sure we ignore SIGPIPE. Start(); // Parse arguments.
return ;
}

测试结果:

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 = ;
long timer15 = ;
ACE_Time_Value time_delay1(, );
ACE_Time_Value time_delay2(, ); 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 --------\n"),*num)); int n = ;
for (int i=; i < ; i++)
{
n++;
}
ACE_DEBUG((LM_INFO, ACE_TEXT("time: %d out ###########\n"),*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 ;
}
protected:
private:
}; ACE_THR_FUNC_RETURN thread_func(void *arg)
{
ACE_TRACE("thread_func(void *)"); ACE_Reactor::instance()->run_reactor_event_loop(); return ;
} 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(, thread_func, , 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 ;
} int ACE_TMAIN(int argc, ACE_TCHAR *argv[])
{
// Make sure we ignore SIGPIPE. Start(); // Parse arguments.
return ;
}

测试结果:

ACE handle_timeout 事件重入的更多相关文章

  1. 使用timer定时器,防止事件重入

    首先简单介绍一下timer,这里所说的timer是指的System.Timers.timer,顾名思义,就是可以在指定的间隔是引发事件.官方介绍在这里,摘抄如下: 1 2 Timer 组件是基于服务器 ...

  2. C#中Timer使用及解决重入问题

    C#中Timer使用及解决重入问题 ★介绍 首先简单介绍一下timer,这里所说的timer是指的System.Timers.timer,顾名思义,就是可以在指定的间隔是引发事件.官方介绍在这里,摘抄 ...

  3. QThread 与 QObject的关系(QObject可以用于多线程,可以发送信号调用存在于其他线程的slot函数,但GUI类不可重入)

    QThread 继承 QObject..它可以发送started和finished信号,也提供了一些slot函数. QObject.可以用于多线程,可以发送信号调用存在于其他线程的slot函数,也可以 ...

  4. UNIX高级环境编程(13)信号 - 概念、signal函数、可重入函数

    信号就是软中断. 信号提供了异步处理事件的一种方式.例如,用户在终端按下结束进程键,使一个进程提前终止.   1 信号的概念 每一个信号都有一个名字,它们的名字都以SIG打头.例如,每当进程调用了ab ...

  5. Use Reentrant Functions for Safer Signal Handling(译:使用可重入函数进行更安全的信号处理)

    Use Reentrant Functions for Safer Signal Handling 使用可重入函数进行更安全的信号处理 How and when to employ reentranc ...

  6. [转]C#中Timer使用及解决重入问题

    本文转自:http://www.cnblogs.com/hdkn235/archive/2014/12/27/4187925.html ★前言 打开久违的Live Writer,又已经好久没写博客了, ...

  7. 关于C#中Timer定时器的重入问题解决方法(也适用于多线程)

    项目中用到了定时器随着服务启动作定时任务,按指定的准点时间定时执行相关操作,但是在指定准点时间内我只想让它执行一次,要避免重入问题的发生. 首先简单介绍一下timer,这里所说的timer是指的Sys ...

  8. 可重入锁ReentrantLock--转载

    突然被问到什么是可重入锁?脑袋里闪过了n中概念,最终没有找到,从网上学习一下. 原文地址:https://www.ibm.com/developerworks/cn/java/j-jtp10264/ ...

  9. Redis分布式锁—Redisson+RLock可重入锁实现篇

    前言 平时的工作中,由于生产环境中的项目是需要部署在多台服务器中的,所以经常会面临解决分布式场景下数据一致性的问题,那么就需要引入分布式锁来解决这一问题. 针对分布式锁的实现,目前比较常用的就如下几种 ...

随机推荐

  1. Bucking the stigma (留学生请摘掉有色眼镜看社区大学)

    Many Chinese students second-guess the benefits of attending a US community college. 很多中国学生对去美国社区大学学 ...

  2. Spark python集成

    Spark python集成 1.介绍 Spark支持python语言,对于大量的SQL类型的操作,不需要编译,可以直接提交python文件给spark来运行,因此非常简单方便,但是性能要比scala ...

  3. 西门子(SIEMENS)软件安装时需要重启的解决方法,regedit restart

    打开注册表(regedit) 删除注册表项 HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manage\PendingFile ...

  4. caffe RandomOrderChannels

    就是将rgb图的3个channel随机打乱顺序,给定一个概率值是否执行这个操作,v系列模型的概率一般都设置的为0 void RandomOrderChannels(const cv::Mat& ...

  5. HttpServletRequest request 获取form参数的两种方式

    @RequestMapping(value="/pay",method = RequestMethod.POST) public String buildRequest(HttpS ...

  6. ROS根据访问不同的网址,走不同的路由策略的脚本

    脚本如下,可以10s一循环计划执行 :global tmpaaa [/ip firewall address-list find list=Not-To-Guowai];foreach i in $t ...

  7. js控制select选中显示不同表单内容

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  8. 第19章 通讯的基本概念—零死角玩转STM32-F429系列

    第19章     通讯的基本概念 全套200集视频教程和1000页PDF教程请到秉火论坛下载:www.firebbs.cn 野火视频教程优酷观看网址:http://i.youku.com/firege ...

  9. HttpServerUtility 和 HttpUyility

    参考:msdn HttpServerUtility 提供用于处理 Web 请求的 Helper 方法. 2017/08/07            加密解码 这个类没有构造函数,所以不能直接new. ...

  10. angularJS 提示

    1.通常angularJS应用程序将模块和控制器包含在JavaScript文件中. 2.在模块的定义中[]参数是用来表示模块的依赖关系. 3.中括号[]为空,表示该模块没有依赖关系,如果有依赖关系的话 ...