应用层除了通过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 ;
}

参考:

1. Linux 下定时器的实现方式分析

应用层timer_libc_posix timer的更多相关文章

  1. 应用层timer_如何序列化timer

    应用层使用timer可以启动多个timer(每个timer管理一个目标时间),也可启用一个timer来管理多个目标时间. 多个timer时每个timer占用一部分空间,且存在多个timer同时到期的先 ...

  2. Linux应用层的定时器Timer使用详解【转】

    转自:http://blog.csdn.net/wwwtovvv/article/details/8601528 版权声明:本文为博主原创文章,未经博主允许不得转载. linux下定时器的使用 -- ...

  3. [Timer]应用层实现sleep

    转自:https://www.cnblogs.com/longbiao831/p/4556246.html Select只能做延时,可以做回调吗? 本文讲述如何使用select实现超级时钟.使用sel ...

  4. C#中自定义高精度Timer定时器的实例教程

    Timer 用于以用户定义的事件间隔触发事件.Windows 计时器是为单线程环境设计的,其中,UI 线程用于执行处理.它要求用户代码有一个可用的 UI 消息泵,而且总是在同一个线程中操作,或者将调用 ...

  5. Linux 应用层的时间编程【转】

    转自:https://blog.csdn.net/chinalj2009/article/details/21223681 浅析 Linux 中的时间编程和实现原理,第 1 部分: Linux 应用层 ...

  6. TCP系列32—窗口管理&流控—6、TCP zero windows和persist timer

    一.简介 我们之前介绍过,TCP报文中的window size表示发出这个报文的一端准备多少bytes的数据,当TCP的一端一直接收数据,但是应用层没有及时读取的话,数据一直在TCP模块中缓存,最终受 ...

  7. TimesTen 应用层数据库缓存学习:4. 仅仅读缓存

    在运行本文样例前.首先先运行TimesTen 应用层数据库缓存学习:2. 环境准备中的操作. Read-only Cache Group的概念 仅仅读缓存组例如以下图: 仅仅读缓存组(Read-Onl ...

  8. 浅析 Linux 中的时间编程和实现原理一—— Linux 应用层的时间编程【转】

    本文转载自:http://www.cnblogs.com/qingchen1984/p/7007631.html 本篇文章主要介绍了"浅析 Linux 中的时间编程和实现原理一—— Linu ...

  9. ABP(现代ASP.NET样板开发框架)系列之15、ABP应用层——应用服务(Application services)

    点这里进入ABP系列文章总目录 基于DDD的现代ASP.NET开发框架--ABP系列之15.ABP应用层——应用服务(Application services) ABP是“ASP.NET Boiler ...

随机推荐

  1. HashTable、List、ArrayList的经典使用和相互转换

    1.添加引用 using System.Collections; 2.创建并添加数据 Hashtable hs = new Hashtable(); hs.Add("Name1", ...

  2. 编译后class$1,class$2,class$innerclass中的$的含义

    本文转自:http://www.cnblogs.com/stefanlee/p/3403445.html class文件名中的$的含义如下:   $后面的类是$前面的类的内部类 内部类有以下两种情况: ...

  3. 几道比较难的SQL题

    上条记录和下一条记录 在展示博客文章时,在文章底部需要展示上一篇文章和下一篇文章,文章的排序当然是按照时间排序的. 选定下一条时可以用limit 1来实现,选取上一条时可以倒序limit 1实现 (S ...

  4. 【LeetCode】164. Maximum Gap (2 solutions)

    Maximum Gap Given an unsorted array, find the maximum difference between the successive elements in ...

  5. Extending and Embedding PHP

    Extending and Embedding PHP http://wizardmin.com/2010/08/extending-and-embedding-php-6/

  6. selenium python学习笔记---添加等待时间

    http://selenium-python.readthedocs.io/waits.html 有时候为了保证脚步运行的稳定性,需要在脚本中添加等待时间 添加休眠:需要引入time包,选择一个固定的 ...

  7. Service和广播联合更新UI的例子

    sa111111 于 2010-11-19 10:56 发表在 [Android实例] [复制链接] [只看楼主] [上一主题] [下一主题]   在Android中,异步更新UI,通常我们会选用Ha ...

  8. Android 监听 Android中监听系统网络连接打开或者关闭的实现代码

    本篇文章对Android中监听系统网络连接打开或者关闭的实现用实例进行了介绍.需要的朋友参考下 很简单,所以直接看代码 复制代码 代码如下: package xxx; import android.c ...

  9. SQL Server 2012 Express LocalDB 的作用

    微软最新推出的 SQL Server 2012 Express LocalDB 是一种 SQL Server Express 的运行模式,特别适合用在开发环境使用,也内置在 Visual Studio ...

  10. Token:服务端身份验证的流行方案【转】

    01- 身份认证 服务端提供资源给客户端,但是某些资源是有条件的.所以服务端要能够识别请求者的身份,然后再判断所请求的资源是否可以给请求者. token是一种身份验证的机制,初始时用户提交账号数据给服 ...