多线程下的多定时器处理

【计算机网络】常见定时器实现方式比较 文章目录常见定时器实现方式比较采用sleep函数采用timerfd + epoll采用链表采用时间轮采用时间堆总结 常见定时器实现方式比较 采用sleep函数 sleep函数在实现时用了SIGALRM信号机制, 在多线程程序中处理信号是个相当麻烦的事情,应当尽量避免 原因: 如果要处理多个定时任务,就要不断触发SIGALRM信号,并在信号处理函数中执行到期任务 在多线程环境下,产生的信号是传递给整个进程的,一般而言,所有线程都有机会收到这个信号,要做特殊的信号阻塞处理、考虑线程安全问题 SIGALRM信号 阅读详情

原文地址:http://hi.baidu.com/sunwater007/blog/item/5f9d71accfa3900f4b36d6d9.html

 问题的提出:多线程中每个线程都需要一个单独的定时器,而且其他线程并不知道该线程中的定时器的存在,由于普通的unix处理定时器的信号方式是一个进程下只能有一个定时器起作用。如果设置多个定时器可能被后续的定时器洗刷掉。那么如何让多个线程独立的使用不同的信号而不被洗刷掉呢?

问题的解决:由于目前的posix里面定义了SIGMIN~SIGMAX信号供用户自定义以扩展程序,那么最好采用此类信号,而不是用32之前的信号;
同时使用sigaction代替signal函数,避免信号丢失的问题;
定时器采用posix TMR方案,不能使用普通的itimer结构。
综上所述,实现的代码如下:
/***********************************************************/
/*
* Because some platforms define different names for signals between SIGMIN and SIGMAX or other
* similar ones. you may use "kill -l" to get these self-defined signals in your platform.
*
* Compile:gcc -lrt -lpthread test.c -o test
* Run:     ./test
*
* By kinghuang, gdnt rnd.
* sunwater007@gmail.com
*/
#include   <stdio.h>
#include   <time.h>
#include   <signal.h>
void timer1_handler(int signo)
{
    static int index = 0;
    
    printf("timer1_handler captures signal: %d, index: %d\n", signo, index++);
}
void timer2_handler(int signo)
{
    static int index = 0;

    printf("timer2_handler, sig: %d, index: %d\n", signo, index++);
}
void set_timer1()
{
    struct sigaction     sig_act;
    struct sigevent      sig_event;
    sigset_t                sig_set;
    struct itimerspec   timer_setting;
    timer_t                 timer_id;
    
    // set sigaction.
    sigemptyset(&sig_act.sa_mask);
    sig_act.sa_flags = 0;
    sig_act.sa_handler = timer1_handler;
    if ( sigaction(SIGRTMIN + 2, &sig_act, NULL) < 0)
    {   printf(" timer1 sigaction meets problem.\n"); return; }
    
    
    sig_event.sigev_notify = SIGEV_SIGNAL;
    sig_event.sigev_signo = SIGRTMIN + 2;
    if ( timer_create(CLOCK_REALTIME, &sig_event, &timer_id) < 0)
    {   printf("create timer1 failed.\n"); return; }
    
    timer_setting.it_value.tv_sec = 1;
    timer_setting.it_value.tv_nsec = 0;
    timer_setting.it_interval.tv_sec = 1;
    timer_setting.it_interval.tv_nsec = 0;
    if ( timer_settime(timer_id, 0, &timer_setting, NULL) < 0)
    {   printf("set timer failed. \n"); return; }
    
    sigemptyset(&sig_set);
    while ( 1)
    {   sigsuspend(&sig_set); }
}
void set_timer2()
{
    struct sigaction     sig_act;
    struct sigevent      sig_event;
    sigset_t                sig_set;
    struct itimerspec   timer_setting;
    timer_t                timer_id;
    
    // set sigaction.
    sigemptyset(&sig_act.sa_mask);
    sig_act.sa_flags = 0;
    sig_act.sa_handler = timer2_handler;
    if ( sigaction(SIGRTMAX - 1, &sig_act, NULL) < 0)
    {   printf(" timer1 sigaction meets problem.\n"); return; }
    
    // set signal event for the timer timeout.
    sig_event.sigev_notify = SIGEV_SIGNAL;
    sig_event.sigev_signo = SIGRTMAX - 1;
    if ( timer_create(CLOCK_REALTIME, &sig_event, &timer_id) < 0)
    {   printf("create timer1 failed.\n"); return; }
    
    // timer setting. The setting can be used by more than one timer.
    timer_setting.it_value.tv_sec = 1;
    timer_setting.it_value.tv_nsec = 0;
    timer_setting.it_interval.tv_sec = 1;
    timer_setting.it_interval.tv_nsec = 0;
    if ( timer_settime(timer_id, 0, &timer_setting, NULL) < 0)
    {   printf("set timer failed. \n"); return; }
    
    sigemptyset(&sig_set);
    // wait for timer timeout.
    while ( 1)
    {   sigsuspend(&sig_set); }
}
int main()
{
    pthread_t t1, t2;
    
    pthread_create(&t1, NULL, (void *)set_timer1, NULL);
    pthread_create(&t2, NULL, (void *)set_timer2, NULL);
    pthread_join(t2, NULL);

    return 0;
}
/************************************************************/
run result:
king>./test
timer2_handler, sig: 63, index: 0
timer1_handler captures signal: 36, index: 0
timer2_handler, sig: 63, index: 1
timer1_handler captures signal: 36, index: 1
timer2_handler, sig: 63, index: 2
timer1_handler captures signal: 36, index: 2
timer2_handler, sig: 63, index: 3
timer1_handler captures signal: 36, index: 3
ctrl+^

从零开始实现一个C++高性能服务器框架----TcpServer模块 项目介绍:实现了一个基于协程的服务器框架,支持多线程、多协程协同调度;支持以异步处理的方式提高服务器性能;封装了网络相关的模块,包括socket、http、servlet等,支持快速搭建HTTP服务器或WebSokcet服务器。详细内容:日志模块,使用宏实现流式输出,支持同步日志与异步日志、自定义日志格式、日志级别、多日志分离等功能。线程模块,封装pthread相关方法,封装常用的锁包括(信号量,读写锁,自旋锁等)。 阅读详情

相关推荐

C++多对象多定时器高级实现指南

定时器事件通常包含如下信息:定时器标识:用于识别不同的定时器。到期时间点:定时器触发的时间。事件处理程序:定时器到期时要执行的操作。

weixin_42551310的博客 784

自适应粒子群优化算法的MATLAB性能仿真

不同的是:进化计算遵循适者生存原则,而PSO模拟社会,将每一个可能产生的解表述为群中的一个微粒,每个微粒都具有自己的位置向量和速度向量,以及一个由目标函数决定的适应度。第六:如此时已满足结束条件,即达到最大的迭代次数或最小的错误要求,则进化终止,输出最优解,否则,转到步骤2。第三:比较每个粒子的适应值和自身所经历过最好位置Pi的适应值,若当前值更好,则将当前值作为自身最好位置;第四:比较每个粒子的适应值和全局最好位置Pg的适应值,若当前值更好,则将当前值作为全局最好位置;第五:更新粒子的速度和位置;

FPGA/MATLAB学习教程/源码/项目合作开发 5358

操作系统简单并发性和多线程处理在real time各种算法下代码

操作系统对于并发性和多线程处理在real time各种算法下的代码实现 使用一个pcb 作为dispathcer 来控制全过程 能正确输出各种算法的处理步骤,CPU 使用情况以及最后运算时间

基于matlab的自适应PSO优化算法仿真

在路径规划中,我们将每一条路径规划为一个粒子,每个粒子群群有 n 个粒 子,即有 n 条路径,同时,每个粒子又有 m 个染色体,即中间过渡点的个数,每 个点(染色体)又有两个维度(x,y),在代码中用 posx 和 posy 表示一个种群。计算新的解 X_{id}' = X_{id} + V_{id} (也就是 V_{id} 作用在 X_{id} 上)计算 P_{id} 与 X_{id} 之间的差 A = P_{id} - X_{id}, 其中 A 为 BSS。更新 P_{gd} 若出现新的全局最好的解。

fpga/matlab/simulink算法仿真工程 1572

linux下多定时器+线程池的实现(经典)

// //linux只允许单进程拥有一个定时器,因此在linux下的单进程中要使用多个定时器,则需要自己维护管理 // //这个实现允许用户使用多个自定义的定时器,每个自定义的定时器将周期地被触发直到其被删除。实现的主要思路是: // // i)首先在初始化多定时器(init_mul_timer)时利用setitimer注册一个基本的时间单位(如1s)的定时事件; // // ii)用户需要set_a_timer注册自定义定时器时,在timer_manage管理结构中记录这个定时器的回调函数和定时周期等参数; // // iii)当基本的时间单位到期后(如SIGALRM信号到达时),遍历整个timer_manage,如果有自定义定时器的超时时间到了, //就把该回调函数添加到线程池的任务中,让线程池里面的线程去执行,然后将自定义定时器的超时时间置为最初值0; // // iv)用户通过del_a_timer来删除某个定时器,通 过destroy_mul_timer来删除整个多定时器。

逆向解析手淘x-sign签名算法:从抓包到API调用的完整实践

本文详细解析了手淘x-sign签名算法的逆向过程,从抓包工具选择到API调用实践,提供了完整的解决方案。通过分析签名参数组成和生成机制,帮助开发者理解并实现淘宝接口的合法调用,同时强调了安全与合规的重要性。

weixin_29323273的博客 606

Qt中定时器TimerID的小总结

Qt中定时器的使用方法 1,如果就用一两个定时器,可以直接使用关联槽函数。      相关教程中 例如: (1)在 mainwindow.h 中添加槽函数声明。 private slots: void timerUpDate(); (2)在 mainwindow.cpp 中添加代码。 添加#include 的头文件包含,这样就包含了QtCore下的所有文件。 构造函数里添加代

6143

caxa二次开发实例展示

本人有8年CAXA各产品(如电子图版、工艺图表、PDM等)二次开发经验,参与过国家电网南瑞集团、中石油、龙记集团、欧姆龙集团、港日集团、中集集团、中国五矿、方圆塑机、大连锅炉、金蝶PDM集成CAXA,TEAMCENTER集成CAXA、大连锅炉机械、中国中车等项目的开发,擅长CAXA电子图版、CAXA工艺图表的二次开发,有需要的可以联系我,电话:13169467685、13249738576 Q

hourui800720的专栏 8029

linux定时器

linux系统中定时器有很多种,alarm, select, setitimer, timer_create等等,这里只简单的介绍两种定时器,setitimer和timer_create。 1.第一种setitimer函数实现定时器 函数原型如下: /* 参数 which:(可选值如下) ITIMER_REAL: 以系统真实的时间来计算,它送出SIGALRM信号。 ITIMER_VIRTUAL:以该进程在用户态下花费的时间来计算,它送出SIGVTALRM信号。 ITIMER_PROF: 以该进程在用户

weixin_44522306的博客 8131

【强化学习】常用算法之一 “A3C”

A3C(Asynchronous Advantage Actor-Critic)算法是一种在强化学习领域中应用广泛的算法,它结合了策略梯度方法和价值函数的学习,用于近似解决马尔可夫决策过程(Markov Decision Process)问题。A3C算法在近年来备受关注,因为它在处理大规模连续动作空间和高维状态空间方面具有出色的性能。A3C算法是一种基于策略梯度的强化学习算法,通过多个并行的智能体异步地与环境交互,并利用Actor和Critic网络实现策略和价值的近似,从而实现快速而稳定的强化学习训练。

Code_and516的博客 6756

CoppeliaSim(原V-REP)新手上路

CoppeliaSim(原V-REP)是一个机器人仿真平台,里面有很多来自别的公司的机器人模型以及完备的物理引擎,我们可以通过python,c++,matlab等语言控制里面的机器人。,您也可以在官网中Downloads里找您需要的版本,一般只需要下载EDU版本就可以了,我下载的是v4.1.0 windows EDU版本。在版本V4之前,CoppeliaSim叫V-REP,在官网可以下载到之前的V-REP版本。

qq_37051669的博客 4万+

信号【N】-linux信号编程的buglist

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录前言一、pandas是什么?二、使用步骤1.引入库2.读入数据总结 前言 提示:这里可以添加本文要记录的大概内容: 例如:随着人工智能的不断发展,机器学习这门技术也越来越重要,很多人都开启了学习机器学习,本文就介绍了机器学习的基础内容。 提示:以下是本篇文章正文内容,下面案例可供参考 一、pandas是什么? 示例:pandas 是基于NumPy 的一种工具,该工具是为了解决数据分析任务而创建的。 二、使用步骤 1.引入库 代.

m0_46535940的博客 523

NVMe-MI 协议解析:带外管理框架与实现原理

本文深入解析了NVMe-MI协议,这是一种用于NVMe固态硬盘的标准化带外管理接口。文章详细阐述了其独立于操作系统的管理框架,通过MCTP协议栈实现,支持SMBus/I2C、PCIe VDM和I3C等物理层,从而在系统故障时仍能可靠地进行健康监控、固件升级等关键运维操作,是现代数据中心存储管理的核心基础设施。

lll78的博客 961

Linux多定时器实现

一、setitimer函数 1. 头文件 #include <sys/time.h> 2. 函数原型 int setitimer(int which, const struct itimerval *new_value, struct itimerval *old_value); which参数说明: ITIMER_REAL:给一个指定的时间间隔,按照实际的时间来减少这个计数,当时间间隔为0的时候发出SIGALRM信号; ITIMER_VIRTUA.

zdw6868的博客 1869

微信小程序|基于小程序实现定位打卡功能

此文主要在小程序内实现打卡功能,可根据用户位置与公司设定的打卡范围实时判断打卡是否合法,并在后台对打卡记录进行管理。

商务合作 / 项目定制 / 学习交流。个人vx:lovely_wml 1万+

uniapp - 微信支付报错 {“errMsg“:“requestPayment:fail:[payment微信:-1]General errors“} 详细解决办法,uniApp使用微信支付时报错

uniapp,微信支付报错,uniapp微信小程序 H5网页 安卓苹果ios真机调试时报错,uniapp真机测试微信支付报错如何解决,调用微信支付出现报错{"errMsg":"requestPayment:fail:[payment微信:-1]General errors"},微信支付提示错误,uniapp进行微信支付时报错怎么解决,如何解决微信支付报错,uniapp微信支付报错fail,uni-app真机测试ios上报错,uniapp真机测试安卓手机第一次支付成功第二次就报错了,uniapp微信支付调用第

✅ 精选推荐文章 4133

已解决:解决 Spring Boot 多线程环境下,多个定时器冲突问题

转发公众号:IT牧场 战术分析: 实际开发项目中一定不止一个定时器,很多场景都需要用到,而多个定时器带来的问题 : 就是如何避免多个定时器的互相冲突 使用场景 : 我们的订单服务,一般会有一个待支付订单,而这个待支付订单是有时间限制的,比如阿里巴巴的订单是五天,淘宝订单是一天,拼多多订单是一天,美团订单是15分钟… 基金系统中,如何同时更新多个存储分区中的基金信息… 总的来说,实际开发中定时器需要解决多个定时器同时并发的问题,也要解决定时器之间的冲突问题 问题不大,说到并发那就离不开多线程

wufaqidong1的博客 469

RK3568驱动 SPI主/从 配置

RK3568 SPI 配置指南 内核配置:启用用户空间驱动(主)和从模式协议支持。 主模式:设备树设置status="okay"、max-freq及引脚复用,子节点compatible="rockchip,spidev"。 从模式:需添加spi-slave属性,子节点命名以slave@X开头。 编译烧写:修改设备树后编译内核或全量镜像,验证/dev/spidevX.Y节点。 测试:使用spidev_test工具,主模式可环回测试,从模式需与主设备通信。 (关键:从模式强制spi-slave和命名规则,频率匹

文石_2009的博客 1146

协程VS多线程 应用场景比对

众所周知 ,多线程除了会给cpu带来切换上下文的开销,还会产生资源竞争,想要用多线程,免不了这里那里加个锁。 所以多线程在有些时候并不讨巧。 所以,协程出现了,他也可以并发的执行多线逻辑,但完全不会给cpu带来额外负担,且不存在任何资源竞争。 看起来,协程可以完美替代多线程了。 但其实,协程也只是在特定应用情境下才适用。 使用多线程的目的之一是为了不阻塞主线程的迭代循环,让主线程可以顺畅...

zwlstc的博客 2808

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

从零开始实现一个C++高性能服务器框架----定时器模块

实现了一个基于协程的服务器框架,支持多线程、多协程协同调度;支持以异步处理的方式提高服务器性能;封装了网络相关的模块,包括socket、http、servlet等,支持快速搭建HTTP服务器或WebSokcet服务器。

qq_44778436的博客 1531

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

Nmodubs4实现单寄存器和多寄存器AO的读写

项目效果图 一、创建plc连接 //用委托对象引用plc_connect方法。 Delegate_Connect connect1 = new Delegate_Connect(plc_connect); ...

chilou7959的博客 1899

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

Java中定时器Timer致命缺点(附学习方法)

目录 简介 案例1:定时器打印Hello World! 线程不死问题? 案例2:单线程问题 定时器实际应用场景 学习方法心得 总结 简介 这篇文章我一直在纠结到底要不要写,不想写一来因为定时器用法比较简单,二来是面试中也不常问。后来还是决定写了主要是想把自己分析问题思路分享给大家,让大家在学习过程中能够参考,学习态度我相信大部分人没有问题,特别是正在看我博文的小伙伴那更不用说了!!给你们点个狂力赞。接下来就是学习方法了,我发现近期来咨询我问题的小伙伴学习姿势不对,所以我用Java中定时器T

duyabc的博客 1077

工业视觉项目避雷:海康VM字符识别SDK开发中‘多图连续运行’与‘实时图像获取’的两种高效方案

本文深入解析海康威视VM SDK在工业视觉字符识别项目中的高效应用,重点解决‘多图连续运行’与‘实时图像获取’两大技术难题。通过定时器+结果封装的稳健方案和内存直读渲染技术,显著提升处理效率和稳定性,适用于工业流水线检测等场景。

weixin_30415113的博客 422

多项操作同时进行,哪种处理方法最好?

R3下要同时始终操作多个进程,使用哪种方法处理为最好?既要确保没有遗漏失误,又要兼顾CPU占用少! 主进程开多个死循环?开多个线程?多个Timer?其它?

陈刚编程心得与知识集 554

从零开始实现一个C++高性能服务器框架----IO协程调度模块

实现了一个基于协程的服务器框架,支持多线程、多协程协同调度;支持以异步处理的方式提高服务器性能;封装了网络相关的模块,包括socket、http、servlet等,支持快速搭建HTTP服务器或WebSokcet服务器。

qq_44778436的博客 1207
上一篇: 编辑器ed介绍
下一篇: C++ STL Vector 函数介绍
ToBe_NotToBe
博客等级 码龄15年 0粉丝 0原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值