多线程运行反应器事件时, 注意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. Java问题定位之Java线程堆栈分析

    采用Java开发的大型应用系统越来越大,越来越复杂,很多系统集成在一起,整个系统看起来像个黑盒子.系统运行遭遇问题(系统停止响应,运行越来越慢,或者性能低下,甚至系统宕掉),如何速度命中问题的根本原因 ...

  2. Java项目性能瓶颈分析及定位(八)——Java线程堆栈分析(五)

    对于CPU而言,常见的瓶颈主要有两种:服务器的压力很小,但是CPU的利用率却很高,这样的性能瓶颈相对比较容易定位(好比我只是说了你一句,你就哭了,你的弱点立马就暴露出来了):给服务器施加的压力很大,但 ...

  3. Node.js-ReferenceError: _filename is not defined

    简直不要被坑得太惨!!!你能?看出来这前面是两根下划线!两根下划线!两根下划线!太尴尬了~找了半天原因居然是这个!

  4. eclipse 上使用tomcat 启动项目,项目目录下无.class 文件

    摘要:在使用eclipse 启动taomcat时,项目报错,但将项目打成war包单独部署到tomcat时,则项目正常,通过对比两次部署文件发现,从eclipse直接启动tomcat时,部署到tomca ...

  5. Vim-命令合集

    命令历史 以:和/开头的命令都有历史纪录,可以首先键入:或/然后按上下箭头来选择某个历史命令. 启动vim 在命令行窗口中输入以下命令即可 vim 直接启动vim vim filename 打开vim ...

  6. 2017.9.22 HTML学习总结--JavaScript脚本语言

    接上: 1.JavaScript脚本语言 定义:javascript是一种简单的脚本语言,可以在浏览器中直接运行, 是一种在浏览器端实现网页与客户交互的技术javascript代码可 以直接运行在ht ...

  7. numpy+pandas+matplotlib+tushare股票分析

    一.数据导入 安装tushare模块包 pip install tushare http://tushare.org/ tushare是一个财经数据接口包 import numpy as np imp ...

  8. Qlikview 数据加载方法罗列

    以下是通常会用到的数据加载的方法,供大家参考: 1. 从文件加载: Data: Load *,RowNo() as InputKey; SQL SELECT ID,TEST,DATECREATED F ...

  9. 缓冲区溢出实战教程系列(三):利用OllyDbg了解程序运行机制

    想要进行缓冲区溢出的分析与利用,当然就要懂得程序运行的机制.今天我们就用动态分析神器ollydbg来了解一下在windows下程序是如何运行的. 戳这里看之前发布的文章: 缓冲区溢出实战教程系列(一) ...

  10. 【翻译】Emmet(Zen Coding)官方文档 之六 自定义 Emmet

    [说明]本系列博文是依据 Emmet 官方文档翻译的,原文地址为:http://docs.emmet.io/,部分内容已经在博主之前的博文中节选过,为方便已经收藏过之前博文的朋友,没有删除这些博文,仅 ...