多线程运行反应器事件时, 注意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. mybatis学习目录

    mybatis详解动态SQL https://www.cnblogs.com/ysocean/p/7289529.html mybatis查询时间段sql语句 http://www.cnblogs.c ...

  2. Linux命令之查看服务进程(ps aux、ps -aux、ps -ef)的运用

    执行ps命令即可列出的是当前服务器进程的快照(时间点),如果想要实时动态的显示进程信息,就可以使用top命令. linux上进程有5种状态:  1. 运行(正在运行或在运行队列中等待)  2. 中断( ...

  3. 用iSee图片专家制作淘宝店标教程

    普通的淘宝店铺都会有店标.店标都显示在店铺首页的显现位置,买家在逛淘宝店的时候,一眼都会瞄到店标.因此,如果可以制作一个专属于自己店铺的店标,可以吸引买家的眼光,也更好地宣传了店铺. 下面就用iSee ...

  4. C#调用C++的dll存在的问题

    C#调用C++写的DLL时,在C#程序中,使用DllImport定义C++导出函数的定义信息,之前在C++中定义导出函数时,使用了long作为参数类型,使用C#调用时,开始在64位版本是哪个测试,一切 ...

  5. 关于vim、nvim的折腾

    1 from a view of enc ·nvim必须set enc=utf8,很多基于python的插件也默认了此,这对于中文这些并不友好,然而,vim支持多字节就好的多. 因为很多项目,大家可能 ...

  6. eplise一键集成工具

    因为要做平台,后台的内容就由我负责,目前想让测试人员  在本地使用eplise可以进行脚本开发,但是很多人都死在了搭建环境的道路上,那我就做了一键集成,点击就可以把所需要的配置项进行配置,总结:实际就 ...

  7. 并查集,是否成树,Poj(1308)

    思路: 对于每一条新的边的两个端点,是否是属于一颗树,要是的话,就不是一颗树.否则,就合并. 这里要注意的是,不能是森林,我这里WA了两次了.只不过在最后,查看每个节点的祖先是否是同一个就可以了. # ...

  8. 2017.10.16 java中getAttribute和getParameter的区别

    (1)getAttribute:表示得到 域中的对象 返回的是OBJ类型;  getParameter:表示 得到 传递的参数 返回的是String类型; 也就是getAttribute获得的值需要进 ...

  9. js 图片库 改进版

    平稳退化 js与html标记分离? 如果有两个函数:firstFunction和secondFunction,如果想让它们俩都在页面加载时得到执行,可以调用函数addLoadEvent,只有一个参数, ...

  10. java 集合 HashSet 实现随机双色球 HashSet addAll() 实现去重后合并 HashSet对象去重 复写 HashCode()方法和equals方法 ArrayList去重

    package com.swift.lianxi; import java.util.HashSet; import java.util.Random; /*训练知识点:HashSet 训练描述 双色 ...