转自:http://www.cnblogs.com/zxouxuewei/p/5095288.html

原创博文,转载请标明出处--周学伟http://www.cnblogs.com/zxouxuewei/

linux操作系统为每一个进程提供了3个内部计时器。

ITIMER_REAL;ITIMER_VIRTUAL;ITIMER_PROF.

ITIMER_REAL:给定一个指定的时间间隔,按照实际的时间来减少这个计数,当时间间隔为0的时候发出SIGALRM信号。

ITIMER_VIRTUAL:给定一个时间间隔,当进程执行的时候才减少计数,时间间隔为0的时候发出SIGVTALRM信号。

ITIMER_PROF:给定一个时间间隔,当进程执行或者是系统为进程调度的时候,减少计数,时间到了,发出SIGPROF信号,这个和TIMER_VIRTUAL联合,常用来计算系统内核时间和用户时间。

看一下getitimer的数据手册

getitimer, setitimer - get or set value of an interval timer

#include <sys/time.h>

int getitimer(int which, struct itimerval *value);

int setitimer(int which, char struct itimerval *value, struct itimerval *ovalue);

ITIMER_REAL;ITIMER_VIRTUAL;ITIMER_PROF.就是三个定时器,在使用的时候,当其中的任何一个时间到了,都会给进程发送一个信号,然后定时器重新被装填,重新开始定时动作。

它们对应的信号

ITIMER_REAL    ---- SIGALRM

ITIMER_VIRTUAL ---- SIGVTALRM

ITIMER_PROF    ---- SIGPROF

函数中的which就是选择这三个定时器中的一个。

下面是描述时间结构体value的

struct itimerval {

struct timeval it_interval; //下一个值

struct timeval it_value;    //当前的值

};

struct timeval {

long tv_sec;  //秒

long tv_usec; //毫秒

};

一个表示时间的结构体,一个含有时间结构体的结构体。

使用定时器的时候,首先定义一个时间结构体,然后初始化这个时间结构体的秒和毫秒。然后使用setitimer函数,第一个参数指定使用哪一个定时器,第二个参数就是传递进去的时间结构体,第三个参数为NULL。这样就设定好了一个定时器了。它就可以开始工作了。

说一下返回值: 函数调用成功返回0, 错误返回-1,并且设置出错值errno。

当出错的时候:可能是value或者是ovalue指针无效;或者是定时器搞错了,不是这三个中的一个;或者是时间结构体中的毫秒超出了0到999999的范围。

由于当定时器的时间到了的时候会引发一个信号,因此我们必须对信号进行处理,因此需要了解一下信号处理的函数。

我们可以修改linux系统信号的相关联的动作,也就是当捕获到某个信号时需要执行什么函数。有点像是可以更改函数指针指向的函数一样。

有这么一个函数可以完成这个问题:sigaction。

也就是sig-action,signal-action,信号动作。

#include<sginal.h>

int sigaction(int signo, const struct sigacton *rstrict act, struct sigaction *restrict oact);

这个函数具有三个参数,第一个是信号的名字,直接写系统的信号名,比如SIGALRM之类的。第二个参数是一个结构体,表述了信号相关的东西,我们 修改的函数指针就在里面。第三个函数是用来返回的,返回该信号的上一个动作,也就是上一个这个信号结构体里面的函数指针指向的函数。

下面看一下这个信号结构体。

struct sigaction {

void (*sa_handler)(int);

sigset_t sa_mask;

int sa_flags;

void (*sa_sigaction)(int, siginfo_t *, void *);

};

在使用的时候,sa_handler和sa_sigaction只是用一个。

sa_mask是和sa_handler一起的。

sa_mask表示了一个信号集合,在调用sigaction之前要先用sigemptyset把sa_mask加入到进程的信号屏蔽字当中。

sigemptyset函数初始化一个sigset_t *类型的信号集合,清除里面的所有信号。

使用函数sigaction(SIGALRM, &tact, NULL)就是把SIGALRM的信号的触发动作变成tact结构体中的sa_handler或者sa_sigaction所指向的函数了。

例子如下,每隔2秒钟打印一行字。

一个函数用来设置信号相关的函数绑定,一个函数用来初始化定时器并且启动它。

然后程序需要运行很久,放到死循环里面去,才能看出来效果,一般的应用程序,都不会自动退出的,往往是永远不退出,或者是等待用户关闭它。

#include<sys/time.h>
#include<stdio.h>
#include<unistd.h>
#include<signal.h>
#include<string.h>
static char msg[] = "time is running out./n";
static int len;
void prompt_info(int signo)
{
write(STDERR_FILENO, msg, len);
}
void init_sigaction(void)
{
struct sigaction tact;
tact.sa_handler = prompt_info;
tact.sa_flags = 0;
sigemptyset(&tact.sa_mask);
sigaction(SIGALRM, &tact, NULL);
}
void init_time()
{
struct itimerval value;
value.it_value.tv_sec = 2;
value.it_value.tv_usec = 0;
value.it_interval = value.it_value;
setitimer(ITIMER_REAL, &value, NULL);
}
int main()
{
len = strlen(msg);
init_sigaction();
init_time();
while(1);
exit(0);
}

linux用户态定时器的使用---19【转】的更多相关文章

  1. linux用户态定时器的使用---19

    原创博文,转载请标明出处--周学伟http://www.cnblogs.com/zxouxuewei/ linux操作系统为每一个进程提供了3个内部计时器. ITIMER_REAL;ITIMER_VI ...

  2. Linux用户态定时器用法以及犯错总结【转】

    转自:http://blog.csdn.net/csdn_logo/article/details/48525703 版权声明:本文为博主原创文章,欢迎转载,转载请注明出处,多谢合作. 采样的时候要用 ...

  3. Linux用户态驱动设计

    聊聊Linux用户态驱动设计   序言 设备驱动可以运行在内核态,也可以运行在用户态,用户态驱动的利弊网上有很多的讨论,而且有些还上升到政治性上,这里不再多做讨论.不管用户态驱动还是内核态驱动,他们都 ...

  4. [中英对照]User-Space Device Drivers in Linux: A First Look | 初识Linux用户态设备驱动程序

    如对Linux用户态驱动程序开发有兴趣,请阅读本文,否则请飘过. User-Space Device Drivers in Linux: A First Look | 初识Linux用户态设备驱动程序 ...

  5. Linux 用户态与内核态的交互【转载】

    Linux 用户态与内核态的交互  在 Linux 2.4 版以后版本的内核中,几乎全部的中断过程与用户态进程的通信都是使用 netlink 套接字实现的,例如iprote2网络管理工具,它与内核的交 ...

  6. linux用户态和内核态通信之netlink机制【转】

    本文转载自:http://blog.csdn.net/zcabcd123/article/details/8272360 这是一篇学习笔记,主要是对<Linux 系统内核空间与用户空间通信的实现 ...

  7. Linux用户态与内核态通信的几种方式

    本文首发于我的公众号 Linux云计算网络(id: cloud_dev),专注于干货分享,号内有 10T 书籍和视频资源,后台回复「1024」即可领取,欢迎大家关注,二维码文末可以扫. Linux 用 ...

  8. Linux用户态程序计时方式详解[转]

    转自: http://www.cnblogs.com/clover-toeic/p/3845210.html 前言 良好的计时器可帮助程序开发人员确定程序的性能瓶颈,或对不同算法进行性能比较.但要精确 ...

  9. Linux用户态和内核态

    究竟什么是用户态,什么是内核态,这两个基本概念以前一直理解得不是很清楚,根本原因个人觉得是在于因为大部分时候我们在写程序时关注的重点和着眼的角度放在了实现的功能和代码的逻辑性上,先看一个例子: 1)例 ...

随机推荐

  1. 第三章 文件 I/O

    3.1 引言 先说明可用的文件 I/O 函数:open.read.write.close,然后说明不同缓冲区长度对read和write函数的影响. 本章所说的函数经常被称为不带缓冲的 I/O (unb ...

  2. POJ 1286 Pólya定理

    Necklace of Beads Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 9162   Accepted: 3786 ...

  3. ISCSI网络存储

    ISCSI(iSCSI,Internet Small Computer System Interface) iSCSI技术实现了物理硬盘设备与TCP/IP网络协议的相互结合,使得用户可以通过互联网方便 ...

  4. Hibernate---架构

    Hibernate 架构是分层的,作为数据访问层,你不必知道底层 API .Hibernate 利用数据库以及配置数据来为应用程序提供持续性服务(以及持续性对象). 下面是一个非常高水平的 Hiber ...

  5. 3771: Triple

    3771: Triple 链接 题意 n个斧头,每个斧头的价值都不同(开始时没注意到),可以取1个,2个,3个斧头组成不同的价值,求每种价值有多少种组成方案(顺序不同算一种) 分析: 生成函数 + 容 ...

  6. linux下多线程断点下载工具-axel

    今天要下载一下14G左右的文件,用wget约10小时,后来发现linux下有个多线程支持断点续传的下载工具axel,试了一下,下载速度大大增加. 包地址:http://pkgs.repoforge.o ...

  7. Swift 与众不同的地方

    Swift 与众不同的地方 switch(元组) 特点 其他语言中的switch语句只能比较离散的整形数据(字符可以转换成整数) 但是swift中可以比较整数.浮点数.字符.字符串.和元组数据类型,而 ...

  8. CV限制符--C++

    C/C++提供多种声明变量和函数存储持续性.作用域和链接性的关键字,有些被称为存储说明符(store class specifier)或 cv 限定符(cv-qualifier),这里就一起学习一下c ...

  9. c# asp.net 中使用token验证

    基于token的鉴权机制类似于http协议也是无状态的,它不需要在服务端去保留用户的认证信息或者会话信息.这就意味着基于token认证机制的应用不需要去考虑用户在哪一台服务器登录了,这就为应用的扩展提 ...

  10. 深入理解net core中的依赖注入、Singleton、Scoped、Transient(四)【转】

    原文链接:https://www.cnblogs.com/gdsblog/p/8465401.html 相关文章: 深入理解net core中的依赖注入.Singleton.Scoped.Transi ...