IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 系统运维 -> linux C定时器总结 -> 正文阅读

[系统运维]linux C定时器总结

概述
linux c本身不支持对timer的封装,使用定时器不像java那样的方便,一般有三种方法使用:1、while+sleep;2、alarm;3、timer_create。下面分别对三种方法进行举例。

一、举例

1、while+sleep

优点是可以完全控制暂停恢复,确定是需要控制线程的生命周期。

#include? <pthread.h>

#include? <sys/time.h>

#include? <stdio.h>

#include? <stdlib.h>

typedef void (*TIMER_CALLBACK)(void);

static int s_wait_time=0;

static TIMER_CALLBACK s_call_back;

static int s_timer_flag=0;

static pthread_t s_pt;

static void sleep_ms(unsigned int msecs)

{

?????? struct timeval tval;

?????? tval.tv_sec????? = msecs / 1000;

?????? tval.tv_usec = (msecs * 1000) % 1000000;

?????? select(0, NULL, NULL, NULL, &tval);

}

//定时器线程

static void* thread_runner(void* param)

{

?????? int time = 0;

?????? printf("thread_run:pthread_self()=[%d]\n",pthread_self());

?????? while(s_timer_flag)

?????? {

????????????? sleep_ms(s_wait_time);

????????????? if(s_call_back!=NULL)

????????????? {

???????????????????? s_call_back();

????????????? }

?????? }

?????? printf("thread_stop:pthread_self()=[%d]\n",pthread_self());

?????? return NULL;

}

//打开定时器

int starttimer(int time_million_second,TIMER_CALLBACK callback)

{

?????? s_wait_time=time_million_second;

?????? s_timer_flag=1;

?????? s_call_back=callback;

?????? pthread_create(&s_pt,NULL,thread_runner,NULL);

}

//关闭定时器

int stoptimer()

{

?????? s_timer_flag = 0;

??????

?????? //暂停定时器也可以结束线程

?????? //pthread_cancel(s_pt);

}

static void timer_routie()

{

?????? static int times = 0;

?????? printf("timer_routie:times=[%d]\n",times++);

}

?int? main()

?{

?????? starttimer(1000,timer_routie);

?????? sleep(5);

?????? stoptimer();

?????? sleep(1);

?}

2、alarm

优点是实现简单,确定是信号会导致sleep和pause提前结束

#include? <unistd.h>

#include? <stdio.h>

#include? <stdlib.h>

#include? <signal.h>



typedef void (*TIMER_CALLBACK)(void);



static int s_wait_time=0;

static TIMER_CALLBACK s_call_back;

static int s_timer_flag=0;



void signal_handler(int siganl)

{

?????? printf("signal_handler:siganl=[%d]\n",siganl);

?????? if(siganl==SIGALRM)

?????? {

????????????? if(s_call_back!=NULL)

????????????? {

?????? ????????????? s_call_back();

???????????????????? alarm(s_wait_time/1000);

????????????? }

?????? }

}



//打开定时器

int starttimer(int time_million_second,TIMER_CALLBACK callback)

{

?????? s_call_back=callback;

?????? s_wait_time=time_million_second;

?????? signal(SIGALRM,signal_handler);

?????? alarm(s_wait_time/1000);

}



//关闭定时器

int stoptimer()

{

?????? s_wait_time=NULL;

}



static void timer_routie()

{

?????? static int times = 0;

?????? printf("timer_routie:times=[%d]\n",times++);

}



?int? main()

?{

?????? int count=5;

?????? starttimer(1000,timer_routie);

??????

?????? //alarm会导致sleep和pause停止阻塞直接返回,所以这里需要循环

?????? while(count--)

?????? {

????????????? pause();

?????? }



?????? stoptimer();



?}

3、timer_create signal模式,此方式也会导致pause、sleep等函数提前返回

#include? <stdio.h>

#include? <stdlib.h>

#include? <signal.h>

#include? <time.h>

typedef void (*TIMER_CALLBACK)(void);

static int s_wait_time=0;

static TIMER_CALLBACK s_call_back;

static pthread_t s_pt;

static timer_t s_timerid;;

void signal_handler(int siganl)

{

?????? printf("signal_handler:siganl=[%d]\n",siganl);

?????? if(siganl==SIGRTMAX)

?????? {

????????????? if(s_call_back!=NULL)

????????????? {

???????????????????? s_call_back();

????????????? }

?????? }

}

//打开定时器

int starttimer(int time_million_second,TIMER_CALLBACK callback)

{

?????? s_wait_time=time_million_second;

?????? s_call_back=callback;

??????

?????? signal(SIGRTMAX,signal_handler);

??????

??????

?????? clockid_t clockid=CLOCK_REALTIME;

?????? struct sigevent sev;

?????? sev.sigev_notify=SIGEV_SIGNAL;

?????? sev.sigev_signo=SIGRTMAX;

?????? sev.sigev_value.sival_ptr=&s_timerid;

?????? //创建定时器

?????? timer_create(clockid,&sev,&s_timerid);

??????

?????? int flags=0;

?????? struct itimerspec new_value;

?????? new_value.it_value.tv_sec=1;

?????? new_value.it_value.tv_nsec=0;

?????? new_value.it_interval.tv_sec=1;

?????? new_value.it_interval.tv_nsec=1;

?????? //struct itimerspec old_value;

?????? //启动定时器

?????? timer_settime(s_timerid,flags,&new_value,NULL);

}

//关闭定时器

int stoptimer()

{

?????? timer_delete(s_timerid);

?????? printf("stoptimer:s_timerid=[%d]\n",s_timerid);

}

static void timer_routie()

{

?????? static int times = 0;

?????? printf("timer_routie:times=[%d]\n",times++);

}

?int? main()

?{

?????? int count=5;

?????? starttimer(1000,timer_routie);

?????? while(count--)

?????? {

????????????? pause();//timer_create也会触发信号量导致sleep/usleep和pause立刻返回

?????? }

?????? stoptimer();

?????? sleep(10);

?}

4、timer_create thread模式,此模式不会导致sleep和pause提前返回,但是会额外创建线程,使用过多的定时器会额外使用内存。

#include? <stdio.h>

#include? <stdlib.h>

#include? <signal.h>

#include? <time.h>



typedef void (*TIMER_CALLBACK)(void);



static int s_wait_time=0;

static TIMER_CALLBACK s_call_back;

static pthread_t s_pt;

static timer_t s_timerid;;



void timer_handler(union sigval sig)

{

?????? printf("signal_handler\n");

?????? if(s_call_back!=NULL)

?????? {

????????????? s_call_back();

?????? }

}



//打开定时器

int starttimer(int time_million_second,TIMER_CALLBACK callback)

{

?????? s_wait_time=time_million_second;

?????? s_call_back=callback;

??????

?????? clockid_t clockid=CLOCK_REALTIME;

?????? struct sigevent sev;

?????? sev.sigev_notify=SIGEV_THREAD;

?????? sev.sigev_signo=SIGRTMAX;

?????? sev.sigev_value.sival_ptr=&s_timerid;

?????? sev.sigev_notify_function=timer_handler;//设置定时器回调

?????? //创建定时器

?????? timer_create(clockid,&sev,&s_timerid);

??????

?????? int flags=0;

?????? struct itimerspec new_value;

?????? new_value.it_value.tv_sec=1;

?????? new_value.it_value.tv_nsec=0;

?????? new_value.it_interval.tv_sec=1;

?????? new_value.it_interval.tv_nsec=1;

?????? //struct itimerspec old_value;

?????? //启动定时器

?????? timer_settime(s_timerid,flags,&new_value,NULL);

}



//关闭定时器

int stoptimer()

{

?????? timer_delete(s_timerid);

?????? printf("stoptimer:s_timerid=[%d]\n",s_timerid);

}



static void timer_routie()

{

?????? static int times = 0;

?????? printf("timer_routie:times=[%d]\n",times++);

}



?int? main()

?{

?????? int count=5;

?????? starttimer(1000,timer_routie);

?????? while(count--)

?????? {

????????????? pause();//timer_create的thread类型不会触发信号量,也就不会导致sleep/usleep和pause立刻返回

?????? }

?????? stoptimer();

?????? sleep(10);

?}

  系统运维 最新文章
配置小型公司网络WLAN基本业务(AC通过三层
如何在交付运维过程中建立风险底线意识,提
快速传输大文件,怎么通过网络传大文件给对
从游戏服务端角度分析移动同步(状态同步)
MySQL使用MyCat实现分库分表
如何用DWDM射频光纤技术实现200公里外的站点
国内顺畅下载k8s.gcr.io的镜像
自动化测试appium
ctfshow ssrf
Linux操作系统学习之实用指令(Centos7/8均
上一篇文章      下一篇文章      查看所有文章
加:2022-05-09 13:09:20  更:2022-05-09 13:10:01 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/15 17:49:57-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码