linux中使用定时器

1.使用14号信号SIGALRM,调用alarm函数

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <signal.h>

void handle(int signum)
{
 printf("hello\n");
}

int main(int argc, const char *argv[])
{
    signal(SIGALRM, handle);
    while(1)
    {
        alarm(3);
        sleep(3);
    }
    return 0;
}

//每隔3秒向自身发送一个SIGALRM信号,signal收到 SIGALRM信号后调用handle进行处理

--》alarm只能精确到秒

2.setitimer  -->也是通过向自身发送信号进行处理的,不过可以精确到毫妙级别

int setitimer(int which, const struct itimerval *new_value,

struct itimerval *old_value);

ITIMER_REAL    decrements in real time, and delivers SIGALRM upon expiration.

ITIMER_VIRTUAL decrements  only  when  the  process  is executing, and delivers

SIGVTALRM upon expiration.

ITIMER_PROF    decrements both when the process executes and when the system is

executing  on  behalf  of the process.  Coupled with ITIMER_VIR-

TUAL, this timer is usually used to profile the  time  spent  by

the  application in user and kernel space.  SIGPROF is delivered

upon expiration.

struct itimerval {

struct timeval it_interval; /* next value */

struct timeval it_value;    /* current value */

};

struct timeval {

long tv_sec;                /* seconds */

long tv_usec;               /* microseconds */

};

--》3种模式产生3中不同的信号,使用方法类似

在该例子中,每隔一秒发出一个SIGALRM,每隔0.5秒发出一个SIGVTALRM信号:

#include <stdio.h>

#include <stdlib.h>

#include <unistd.h>

#include <signal.h>

#include <time.h>

#include <sys/time.h>

int sec;

void sigroutine(int signo){

switch (signo){

case SIGALRM:

printf("Catch a signal -- SIGALRM \n");

signal(SIGALRM, sigroutine);

break;

case SIGVTALRM:

printf("Catch a signal -- SIGVTALRM \n");

signal(SIGVTALRM, sigroutine);

break;

}

fflush(stdout);

return;

}

int main()

{

struct itimerval value, ovalue, value2; //(1)

sec = 5;

printf("process id is %d\n", getpid());

signal(SIGALRM, sigroutine);

signal(SIGVTALRM, sigroutine);

value.it_value.tv_sec = 1;

value.it_value.tv_usec = 0;

value.it_interval.tv_sec = 1;

value.it_interval.tv_usec = 0;

setitimer(ITIMER_REAL, &value, &ovalue); //(2)

value2.it_value.tv_sec = 0;

value2.it_value.tv_usec = 500000;

value2.it_interval.tv_sec = 0;

value2.it_interval.tv_usec = 500000;

setitimer(ITIMER_VIRTUAL, &value2, &ovalue);

for(;;)

;

}

3.timerfd_create   timerfd_settime   -->通过时间设置fd可读,然后通过select轮询,调用处理函数

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/timerfd.h>
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>
#include <errno.h>

#define ERR_EXIT(m)     do {         perror(m);        exit(EXIT_FAILURE);    }while(0)

int main(int argc, const char *argv[])
{
    struct itimerspec time;
    time.it_value.tv_sec = 5;
    time.it_interval.tv_sec = 2;

    int timerfd = timerfd_create(CLOCK_REALTIME, 0);
    if(timerfd == -1)
        ERR_EXIT("timerfd_create");

    if(timerfd_settime(timerfd, 0, &time, NULL) == -1)
        ERR_EXIT("timerfd_settime");

    fd_set read1, ready;
    FD_ZERO(&read1);
    FD_SET(timerfd, &read1);
    char buf[1024];
    struct timeval time_select;
    while(1)
    {
        time_select.tv_sec = 3;//必须定义在while内部
        time_select.tv_usec = 11;
        ready = read1;
        int nready = select(timerfd + 1, &ready, NULL, NULL, &time_select);//设置为一直阻塞
        if(nready == -1)
            ERR_EXIT("select");
        else if(nready == 0)
            printf("timeout");
        else
        {
            if(-1 == read(timerfd, buf, sizeof buf))
            {
                printf("%s\n", strerror(errno));//打印错误信息
                ERR_EXIT("read");
            }
            printf("come\n");
        }
    }
    return 0;
}

4.直接使用select   -->精确到毫秒级别

int msSleep(long ms) {

    struct timeval tv;

    tv.tv_sec = 0;

    tv.tv_usec = ms;

     return select(0, NULL, NULL, NULL, &tv);
}

其他资料:

http://www.cppblog.com/CppExplore/archive/2008/04/02/46111.html



时间: 2024-10-17 03:45:17

linux中使用定时器的相关文章

手把手教你写Linux设备驱动---定时器(一)(基于友善之臂4412开发板)

这个专题我们来说下Linux中的定时器. 在Linux内核中,有这样的一个定时器,叫做内核定时器,内核定时器用于控制某个函数,也就是定时器将要处理的函数在未来的某个特定的时间内执行.内核定时器注册的处理函数只执行一次,即不是循环执行的. 如果对延迟的精度要求不高的话,最简单的实现方法如下---忙等待: Unsigned long j = jiffies + jit_delay * HZ; While(jiffies < j) { -- } 下面来说下具体的参数代表的含义: jiffies:全局变

【翻译】TCP backlog在Linux中的工作原理

原文How TCP backlog works in Linux水平有限,难免有错,欢迎指出!以下为翻译: 当应用程序通过系统调用listen将一个套接字(socket)置为LISTEN状态时,需要为该套接字指定一个backlog参数,该参数通常被描述为用来限制进来的连接队列长度(queue of incoming connections). 由于TCP协议的三次握手机制,一个进来的套接字连接在进入ESTABLISHED状态并且可以被accept调用返回给应用程序之前,会经历中间状态SYN RE

Linux下的定时器:alarm()与setitimer()

Linux下的定时器有两种,以下分别介绍: 1.alarm 如果不要求很精确的话,用alarm()和signal()就够了 unsigned int alarm(unsigned int seconds) 函数说明: alarm()用来设置信号SIGALRM在经过参数seconds指定的秒数后传送给目前的进程.如果参数seconds为0,则之前设置的闹钟会被取消,并将剩下的时间返回. 返回值: 返回之前闹钟的剩余秒数,如果之前未设闹钟则返回0. alarm()执行后,进程将继续执行,在后期(al

linux中C语言发送广播报文

2. 指令的解决方法: oute add -net 255.255.255.255 netmask 255.255.255.255 dev eth0 metric 1 或者 route add -host 255.255.255.255 dev eth0 需要用到函数:setsockopt(); setsockopt()函数,用于任意类型.任意状态套接口的设置选项值.尽管在不同协议层上存在选项,但本函数仅定义了最高的"套接口"层次上的选项. #include <sys/types

Linux中select函数

转载自:http://blog.163.com/henry_hlh/blog/static/17039507420124211841298/ Unix中的函数select和poll用来,支持Unix中I/O复用的功能,在Unix中I/O模型可以分为以一几种: (1)阻塞I/O (2)非阻塞I/O (3)I/O复用(select和poll) (4)信号驱动I/O(SIGIO) (5)异步I/O 其中,现在比较流行的I/O模型是阻塞I/O模型.阻塞I/O是当应用程序和内核交换数据时,由于内核还没有准

Linux中进程控制块PCB-------task_struct结构体结构

Linux中task_struct用来控制管理进程,结构如下: struct task_struct { //说明了该进程是否可以执行,还是可中断等信息    volatile long state;   //Flage 是进程号,在调用fork()时给出 unsigned long flags;   //进程上是否有待处理的信号 int sigpending;    //进程地址空间,区分内核进程与普通进程在内存存放的位置不同 mm_segment_t addr_limit; //0-0xBF

task_struct结构体字段介绍--Linux中的PCB

task_struct结构体 字段介绍 Linux内核通过一个被称为进程描述符的task_struct结构体来管理进程, task_struct是Linux中的[进程控制块PCB结构]的具体数据结构 这个结构体包含了一个进程所需的所有信息.它定义在linux-2.6.38.8/include/linux/sched.h文件中. 下面对task_struct这个结构体 进行各个字段的详细介绍 1. 调度数据成员(1) volatile long states;表示进程的当前状态:? TASK_RU

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

本文转载自:http://www.cnblogs.com/qingchen1984/p/7007631.html 本篇文章主要介绍了"浅析 Linux 中的时间编程和实现原理一—— Linux 应用层的时间编程",主要涉及到浅析 Linux 中的时间编程和实现原理一—— Linux 应用层的时间编程方面的内容,对于浅析 Linux 中的时间编程和实现原理一—— Linux 应用层的时间编程感兴趣的同学可以参考一下. 简介: 本文试图完整地描述 Linux 系统中 C 语言编程中的时间问

linux 中常用的一些头文件

#include <linux/***.h> 是在linux-2.6.29/include/linux下面寻找源文件. #include <asm/***.h> 是在linux-2.6.29/arch/arm/include/asm下面寻找源文件. #include <mach/***.h> 是在linux-2.6.29/arch/arm/mach-s3c2410/include/mach下面寻找源文件. #include <plat/regs-adc.h>