Unix环境编程之定时、信号与中断

在linux下实现精度较高的定时功能,需要用到setitimer 和 getitimer函数。

函数原型:

#include <sys/time.h>
int getitimer(int which, struct itimerval *curr_value);
int setitimer(int which, const struct itimerval *new_value,
                     struct itimerval *old_value);

· 函数getitimer()把指定的定时器类型( ITIMER_REAL,  ITIMER_VIRTUAL,  或 ITIMER_PROF中的一个)写入curr_value指向的结构。

it_value设置为定时器剩余时间(若定时器关闭则为0)。类似的,it_interval设置为复位时间。

分析形参:

1. int which

  which为定时器类型,setitimer支持3种类型的定时器:

ITIMER_REAL: 以系统真实的时间来计算,它送出SIGALRM信号。

ITIMER_VIRTUAL: -以该进程在用户态下花费的时间来计算,它送出SIGVTALRM信号。

ITIMER_PROF: 以该进程在用户态下和内核态下所费的时间来计算,它送出SIGPROF信号。

2. const struct itimerval *value

  value 是一个指向itimerval类型的指针,介绍如下

struct itimerval
{
    struct timeval it_interval;//next value
    struct timeval it_value;//current value
};

timeval也是一个数据类型:

struct timeval
{
    long tv_sec;
    long tv_usec;
};

  it_interval指定间隔时间,it_value指定初始定时时间。如果只指定it_value,就是实现一次定时;如果同时指定 it_interval,则超时后,系统会重新初始化it_value为it_interval,实现重复定时;两者都清零,则会清除定时器。tv_sec提供秒级精度,tv_usec提供微秒级精度,以值大的为先。

3. struct itimerval *ovalue

  ovalue用来保存先前的值,通常设置为NULL。

每次定时循环结束会产生中断,通常会用到signal函数捕捉处理,原型为:

#include<signal.h>
void  (* signal(int sig, void (*func) (int)) ) (int);

  signal()是一个系统调用,常用来设定某个信号(sig)的处理方法(func):

信号类型(sig)

(1) 与进程终止相关的信号。当进程退出,或者子进程终止时,发出这类信号。

(2) 与进程例外事件相关的信号。如进程越界,或企图写一个只读的内存区域(如程序正文区),或执行一个特权指令及其他各种硬件错误。

(3) 与在系统调用期间遇到不可恢复条件相关的信号。如执行系统调用exec时,原有资源已经释放,而目前系统资源又已经耗尽。

(4) 与执行系统调用时遇到非预测错误条件相关的信号。如执行一个并不存在的系统调用。

(5) 在用户态下的进程发出的信号。如进程调用系统调用kill向其他进程发送信号。

(6) 与终端交互相关的信号。如用户关闭一个终端,或按下break键等情况。

(7) 跟踪进程执行的信号。

下列宏常量表达式指定了标准的信号值:

Marcro Signal
SIGABRT 异常终止,如调用abort().
SIGFPE 如除0或操作结果溢出(不一定是浮点操作).
SIGILL 非法指令或无效的函数镜像,通常由于代码错误或执行数据引起.
SIGINT 交互式中断信号,通常由用户产生.
SIGSEGV 段冲突.访问非法存储空间时产生.
SIGTERM 发给本程序的中止信号.

处理方法(func)有三种,分别是:

  默认处理(SIG_DFL), 信号以其默认指定的行为进行处理。

  忽略信号(SIG_IGN), 信号被忽略而且程序会继续往下执行,即使没有任何意义。

  函数处理,以用户指定的函数来处理信号。

仅看原型比较抽象,举个例子就知道了:

  

#include<stdio.h>
#include<sys/time.h>
#include<signal.h>

void response(void);
int main()
{
    struct itimerval my_timer;
    long n_sec, n_usec;
    my_timer.it_interval.tv_sec = 0;
    my_timer.it_interval.tv_usec = 300*1000;//300ms
    my_timer.it_value.tv_sec = 2;   //2s
    my_timer.it_value.tv_usec = 0;

    setitimer(ITIMER_REAL, &my_timer, NULL);

    signal(SIGALRM,(__sighandler_t)&response);
    while(1)
        ;
    return 0;
}

void response(void)
{
    printf("Receive signal!!\n");
}

上述代码片段将定时器初始值设为2s,循环值为300ms,则当setitimer函数执行以后2s产生SIGALRM中断,由signal函数指定中断处理函数为response();

2s之后,每隔300ms产生一次SIGALRM中断。

参考文章:

http://www.uml.org.cn/c%2B%2B/200812083.asp

时间: 2024-11-10 01:06:41

Unix环境编程之定时、信号与中断的相关文章

UNIX环境编程学习——反思认识

 学习情况: 有关UNIX系统环境编程的学习时间用来很长的时间,但是感觉效果还是不是太好,在中间经过了期末考试,用来很长的时间用来学习专业课,就将该过程的学习放到了一边上,放假以后又回家造成了中间的学习时间打的很散,又由于自己的水平还是十分有限的,所以该过程的学习效果感觉不太好,时间的观念在脑中还是不够强烈,整个过程中总体来说只是在总体上了解了一个大概,实践还差的很远. 学习期间博客: 1.UNIX环境编程初步认识--编程环境搭建 2.UNIX环境编程初步认识--文件和I/O 3.UNIX环

unix环境编程 文件操作

1.  文件的打开读写 关闭 int open(const char *pathname,int flag,-)   打开一个文件 成功则返回文件描述符,若出现则返回-1 flag可以取下面的常量 O_RDONLY  只读打开 O_WRONLY  只写打开 O_RDWR    读写打开 其它的常量 O_APPEND,O_CREAT,O_EXCL,O_TRUNC,O_NOCTTY,O_NONBLOCK是可选的. int create(const char *pathname,mode_t mode

unix环境编程 目录操作

1.目录操作有 mkdir(constchar *pathname,mode_t mode) 创建目录,成功则返回0,若出错则返回-1 int rmdir(const char *pathname) rmdir可以删除一个空目录,成功则返回0,若出错返回-1 DIR *opendir(const *pathname) 成功则返回指针,若出错则返回NULL struct dirent *readdir(DIR *dp) 若成功则返回指针,出处则返回NULL void rewinddir(DIR *

unix环境编程 tcp通信

TCP通信的过程为: 一. 服务器端: 1.socket(int domain,int type,int protocol):建立套接字: 2 .bind(int sockid,struct sockaddr *addrp,socklen_t addrlen):绑定端口和地址信息: 3.listen(int sockid,int qsize):监听套接字; 4.fd=accept(int sockid,struct sockaddr *callerid,socklen_t *addrlenp):

APUE《UNIX 环境编程》读后感

今天终于把APUE前17章全部看完了,基本上主要知识就在这些章节里. 之前看完<unix/linux编程实践教程>时,有一种豁然开朗.心旷神怡的感觉,在代码级别了解了linux很多系统机制,和一直不理解编程细节,而且对UNIX编程的整体知识结构有了很好的把握. APUE是公认的经典,事无巨细的把每个知识讲解很透,还有很多细心的提示.但是看起来的过程并不觉得那么美好,原因有以下几点: 1.译者那糟糕的水平!很多句子根本就不是中国人能说口的.无奈英语烂,顶多能看看man的水平,只能看中文版了.这本

UNIX环境编程学习笔记(24)——信号处理进阶学习之信号集和进程信号屏蔽字

lienhua342014-11-03 1 信号传递过程 信号源为目标进程产生了一个信号,然后由内核来决定是否要将该信号传递给目标进程.从信号产生到传递给目标进程的流程图如图 1 所示, 图 1: 信号产生.传递到处理的流程图 进程可以阻塞信号的传递.当信号源为目标进程产生了一个信号之后,内核会执行依次执行下面操作, 1. 如果目标进程设置了忽略该信号,则内核直接将该信号丢弃. 2. 如果目标进程没有阻塞该信号,则内核将该信号传递给目标进程,由目标进程执行相对应操作. 3. 如果目标进程设置阻塞

Unix NetWork Programming(unix环境编程)——环境搭建(解决unp.h等源码编译问题)

此配置实例亲测成功,共勉,有问题大家留言. 环境:VMware 10 + unbuntu 14.04 为了unix进行网络编程,编程第一个unix程序时遇到的问题,不能包含unp.h文件,这个感觉和apue.h差不多,不过这里需要编译源代码,为了以后方便,现在整理如下: 主要有两点一是生成libunp.a这个库,二是得到unp.h.config.h这两个个头文件. 1,安装编译器,为了齐全还是安装一下build-essential sudo apt-get install build-essen

UNIX环境编程学习笔记(23)——信号处理初步学习

lienhua342014-10-29 1 信号的概念 维基百科中关于信号的描述是这样的: 在计算机科学中,信号(英语:Signals)是 Unix.类 Unix 以及其他 POSIX 兼容的操作系统中进程间通讯的一种有限制的方式.它是一种异步的通知机制,用来提醒进程一个事件已经发生.当一个信号发送给一个进程,操作系统中断了进程正常的控制流程,此时,任何非原子操作都将被中断.如果进程定义了信号的处理函数,那么它将被执行,否则就执行默认的处理函数. 关于这段描述,我们可以从中学习到下面几点关于信号

UNIX环境编程学习笔记(22)——进程管理之system 函数执行命令行字符串

lienhua342014-10-15 ISO C 定义了 system 函数,用于在程序中执行一个命令字符串.其声明如下, #include <stdlib.h> int system(const char *cmdstring); system 函数在其实现中调用了 fork.exec 和 waitpid 函数.system 函数调用 fork 函数创建子进程,然后由子进程调用’/bin/sh -c cmdstring’ 来执行命令行参数 cmdstring,此命令执行完后便返回调用的进程