应用层timer_libc_posix timer
应用层除了通过setitimer/getitimer设置获取timer外,还可通过timer_create()等一系列函数实现应用层timer功能。
应用流程
The timers created by timer_create() are commonly known as "POSIX (interval) timers". The POSIX timers API consists of the following interfaces:
* timer_create(): Create a timer.
* timer_settime(2): Arm (start) or disarm (stop) a timer.
* timer_gettime(2): Fetch the time remaining until the next expiration of a timer, along with the interval setting of the timer.
* timer_getoverrun(2): Return the overrun count for the last timer expiration.
* timer_delete(2): Disarm and delete a timer.
timer_create
#include <signal.h>
#include <time.h> int timer_create(clockid_t clockid, struct sigevent *sevp, timer_t *timerid);
timer_create() creates a new per-process interval timer. The ID of the new timer is returned in the buffer pointed to by timerid, which must be a non-null pointer.
参数clockid
CLOCK_REALTIME A settable system-wide real-time clock. 一般此id。
CLOCK_MONOTONIC
A nonsettable monotonically increasing clock that measures time from some unspecified point in the past that does not change after system startup.
CLOCK_PROCESS_CPUTIME_ID (since Linux 2.6.12)
A clock that measures (user and system) CPU time consumed by (all of the threads in) the calling process.
CLOCK_THREAD_CPUTIME_ID (since Linux 2.6.12)
A clock that measures (user and system) CPU time consumed by the calling thread.
参数sigevent
指定超时的动作,详见man sigevent。
The sevp.sigev_notify field can have the following values:SIGEV_NONE(不处理),SIGEV_SIGNAL(产生信号),SIGEV_THREAD(新线程处理),SIGEV_THREAD_ID(指定线程处理)。
参数timerid
typedef void * timer_t; timer_t timerid;
printf("timer ID is 0x%lx\n", (long)timerid);
返回值
成功返回0,timerid保存创建的timer。
manpage示例--SIGEV_SIGNAL:
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <signal.h> #define SIG SIGTERM #define errExit(msg) \
do {perror(msg); exit(EXIT_FAILURE); } while() static void print_siginfo(siginfo_t *si)
{
timer_t *tidp;
int or; tidp = si->si_value.sival_ptr; printf("sigval_ptr = %p; ", si->si_value.sival_ptr);
printf(" *sival_ptr =0x%lx\n", (long) *tidp); or = timer_getoverrun(*tidp);
if(or == -){
errExit("timer_getoverrun");
} else {
printf(" overrun count = %d\n", or);
}
} static void handler(int sig, siginfo_t *si, void *uc)
{
/* Note: calling printf() from a signal handler is not
strictly correct, since printf() is not async-signal-safe;
see signal(7) */
printf("Caught signal %d\n", sig);
print_siginfo(si);
signal(sig, SIG_IGN);
}
int main(int argc, char **argv)
{
int ret = ;
timer_t timerid;
struct sigevent se;
struct itimerspec its;
long long freq_nanosecs;
sigset_t mask;
struct sigaction sa; if(argc != ){
fprintf(stderr, "Usage:%s <sleep-secs> <freq_nanosecs>\n", argv[]);
exit(EXIT_FAILURE);
} printf("Establishing handler for signal %d\n", SIG);
sa.sa_flags = SA_SIGINFO;
sa.sa_sigaction = handler;
sigemptyset(&sa.sa_mask);
if(sigaction(SIG, &sa, NULL) == -){
errExit("sigaction");
} printf("Blocking signal %d\n", SIG);
sigemptyset(&mask);
sigaddset(&mask, SIG);
if(sigprocmask(SIG_SETMASK, &mask, NULL) == -){
errExit("sigprocmask");
} memset(&se, , sizeof(struct sigevent));
se.sigev_notify = SIGEV_SIGNAL;
se.sigev_signo = SIG;
se.sigev_value.sival_ptr = &timerid;
ret = timer_create(CLOCK_REALTIME, &se, &timerid);
if(!ret){
printf("timer create successfully, timeid is 0x%lx\n", (long)timerid);
} else {
perror("timer_create");
} /* Start the timer */
freq_nanosecs = atoll(argv[]);
its.it_value.tv_sec = freq_nanosecs /;
its.it_value.tv_nsec = freq_nanosecs %;
its.it_interval.tv_sec = freq_nanosecs /;
its.it_interval.tv_nsec = freq_nanosecs %; if(timer_settime(timerid, , &its, NULL) == -){
errExit("timer_settime");
}
printf("Sleeping for %d secs\n", atoi(argv[]));
sleep(atoi(argv[])); printf("Unblocking signal %d\n", SIG);
if(sigprocmask(SIG_UNBLOCK, &mask, NULL) == -){
errExit("sigprocmask");
} exit(EXIT_SUCCESS);
}
SIGEV_THREAD示例:
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
#include <signal.h>
#include <time.h> //void * timer_thread(void *arg)
void timer_thread(union sigval sv)
{
printf("thread run: %lu...[%s]\n", pthread_self(), (char *)sv.sival_ptr);
// printf("thread run: %lu...[%d]\n", pthread_self(), (char *)sv.sival_int); // return NULL;
} timer_t timer_add(long sec, long usec, void (*func)(union sigval), void *arg)
{
int ret = ;
timer_t tid;
struct sigevent sev; memset(&sev, , sizeof(sev));
sev.sigev_notify = SIGEV_THREAD;
sev.sigev_notify_function = func;
sev.sigev_value.sival_ptr = arg; ret = timer_create(CLOCK_MONOTONIC, &sev, &tid);
if(ret < ){
printf("timer_create failed.\n");
return (timer_t)-;
}else {
printf("create timer id: %lx\n", (long)tid);
} struct itimerspec its; memset(&its, , sizeof(its));
its.it_interval.tv_sec = sec;
its.it_interval.tv_nsec = usec * ;
its.it_value.tv_sec = ;
its.it_value.tv_nsec = ; ret = timer_settime(tid, , &its, NULL);
if(ret < ){
printf("timer_settime failed.\n");
return (timer_t)-;
} return tid;
} int main(int argc, char *argv[])
{
timer_t tid;
char str[] ="I love CHINA";
/*
int ret = 0;
pthread_t thid = 0; ret = pthread_create(&thid, NULL, timer_thread, NULL);
if(ret < 0){
printf("create thread failed.\n");
return -1;
}
ret = pthread_detach(thid);
if(ret < 0){
printf("pthread_detach failed.\n");
return -1;
}
*/
tid = timer_add(, , timer_thread, (void *)str);
if(tid < ){
printf("timer add failed.\n");
return -;
} while();
// sleep(5); timer_delete(tid);
return ;
}
参考:
应用层timer_libc_posix timer的更多相关文章
- 应用层timer_如何序列化timer
应用层使用timer可以启动多个timer(每个timer管理一个目标时间),也可启用一个timer来管理多个目标时间. 多个timer时每个timer占用一部分空间,且存在多个timer同时到期的先 ...
- Linux应用层的定时器Timer使用详解【转】
转自:http://blog.csdn.net/wwwtovvv/article/details/8601528 版权声明:本文为博主原创文章,未经博主允许不得转载. linux下定时器的使用 -- ...
- [Timer]应用层实现sleep
转自:https://www.cnblogs.com/longbiao831/p/4556246.html Select只能做延时,可以做回调吗? 本文讲述如何使用select实现超级时钟.使用sel ...
- C#中自定义高精度Timer定时器的实例教程
Timer 用于以用户定义的事件间隔触发事件.Windows 计时器是为单线程环境设计的,其中,UI 线程用于执行处理.它要求用户代码有一个可用的 UI 消息泵,而且总是在同一个线程中操作,或者将调用 ...
- Linux 应用层的时间编程【转】
转自:https://blog.csdn.net/chinalj2009/article/details/21223681 浅析 Linux 中的时间编程和实现原理,第 1 部分: Linux 应用层 ...
- TCP系列32—窗口管理&流控—6、TCP zero windows和persist timer
一.简介 我们之前介绍过,TCP报文中的window size表示发出这个报文的一端准备多少bytes的数据,当TCP的一端一直接收数据,但是应用层没有及时读取的话,数据一直在TCP模块中缓存,最终受 ...
- TimesTen 应用层数据库缓存学习:4. 仅仅读缓存
在运行本文样例前.首先先运行TimesTen 应用层数据库缓存学习:2. 环境准备中的操作. Read-only Cache Group的概念 仅仅读缓存组例如以下图: 仅仅读缓存组(Read-Onl ...
- 浅析 Linux 中的时间编程和实现原理一—— Linux 应用层的时间编程【转】
本文转载自:http://www.cnblogs.com/qingchen1984/p/7007631.html 本篇文章主要介绍了"浅析 Linux 中的时间编程和实现原理一—— Linu ...
- ABP(现代ASP.NET样板开发框架)系列之15、ABP应用层——应用服务(Application services)
点这里进入ABP系列文章总目录 基于DDD的现代ASP.NET开发框架--ABP系列之15.ABP应用层——应用服务(Application services) ABP是“ASP.NET Boiler ...
随机推荐
- <转>C++ explicit关键字详解
要文转自:http://www.cnblogs.com/ymy124/p/3632634.html 首先, C++中的explicit关键字只能用于修饰只有一个参数的类构造函数, 它的作用是表明该构造 ...
- 【LeetCode】14. Longest Common Prefix (2 solutions)
Longest Common Prefix Write a function to find the longest common prefix string amongst an array of ...
- Java虚拟机学习 - 对象访问 (2)
对象访问会涉及到Java栈.Java堆.方法区这三个内存区域. 如下面这句代码: Object objectRef = new Object(); 假设这句代码出现在方法体中,"Object ...
- 工作总结 EntityFramework中出现DateTime2异常的完美解决办法
EntityFramework中出现DateTime2异常的完美解决办法 今天在使用entityframework往数据库插入数据的时候,突然出现了一个数据类型转换异常的问题: System.Da ...
- mvc中Action前HttpPost的作用
本文导读:在ASP.NET MVC框架中,为了限制某个action只接受HttpPost的请求,对于HttpGet的请求则提示404找不到页面,可以在action的方法前面加上[HttpPost]属性 ...
- python学习笔记——进程间通信方式对比
通信方式对比 管道 消息队列 共享内存 信号 开辟空间 内存 内存 内存 不开辟额外空间 读写方式 双向/单向(信息流) 先进先出(消息体) 操作内存(数值数组) 发送处理信号 效率 一般 一般 ...
- RHCE7 -- IPv6
IPV6地址一个128位数字 如果在IPv6地址后面包括TCP和UDP网络端口,建议将IPv6放在方括号中,以便区分: [2001:db8:0:10::1]:80 IPv6的标准子网掩码是&q ...
- Python rfind()方法
描述 Python rfind() 返回子字符串最后一次出现在字符串中的索引位置,该方法与rindex() 方法一样,只不过如果子字符串不在字符串中不会报异常,而是返回-1. 语法 rfind() 方 ...
- window 环境 Composer 安装 thinkphp5
参考链接:https://www.kancloud.cn/thinkphp/thinkphp5_quickstart/478269 在 Windows 中,你需要下载并运行 Composer-Setu ...
- windows下配置nginx+php环境(转)
刚看到nginx这个词,我很好奇它的读法(engine x),我的直译是“引擎x”,一般引“擎代”表了性能,而“x”大多出现是表示“xtras(额外的效果)”,那么整个词的意思就是类似“极致效果”,“ ...