Linux下定时器的使用(alarm,timer_create)

本文介绍了两种定时器机制:alarm和timer_create。通过示例代码详细解释了如何使用这两种方法实现进程定时操作。alarm用于简单定时任务,而timer_create提供更灵活的定时功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1、alarm

  如果不要求很精确的话,用alarm()和signal()就够了。

  unsigned int alarm(unsigned int seconds)

  函数说明: alarm()用来设置信号SIGALRM在经过参数seconds指定的秒数后传送信号SIGALRM给目前的进程。如果参数seconds为0,则之前设置的闹钟会被取消,并将剩下的时间返回,alarm只触发一次信号。

  返回值: 返回之前闹钟的剩余秒数,如果之前未设闹钟则返回0.

  alarm()执行后,进程将继续执行,在后期(alarm以后)的执行过程中将会在seconds秒后收到信号SIGALRM并执行其处理函数。

#include <stdio.h>
#include <sys/time.h>
#include <stdlib.h>
#include <signal.h>
#include <unistd.h>
int count;
void sigalrm_func(int sig){
    count++;
    printf("alarm![%d]\n",count);
    //alarm(2);
    printf("over\n");
    return; 
}

int main(void){
    signal(SIGALRM, sigalrm_func);
    alarm(3);
    printf("see\n");
    while(1);
 }

 2、timer_create



void timer_timeout(int signal)
{
    if(SIGUSR1 == signal)
    {
		printf("####setitimer_timeout\n");		
    }
}


void settimer(int nsec)
{
	struct itimerspec  tInterval;

	tInterval.it_value.tv_sec     = nsec / 1000000000;  //首次超时时间
    tInterval.it_value.tv_nsec    = nsec % 1000000000;  
    tInterval.it_interval.tv_sec  = 5;  //以后超时间隔(0表示只有第一次)
    tInterval.it_interval.tv_nsec = 0; 
	
	if (timer_settime(timer, 0, &tInterval, 0) == -1) 
	{
		printf("fail to timer_settime");
		exit(-1);
	}
}


void init_timer()
{
	struct sigevent evp;
	 
    signal(SIGUSR1, setitimer_timeout);//注册信号处理函数和sing no
	
    memset(&evp, 0, sizeof(struct sigevent));
    evp.sigev_signo  = SIGUSR1;
    evp.sigev_notify = SIGEV_SIGNAL;
	
    if (-1 ==  timer_create(CLOCK_REALTIME, &evp, &timer))
	{
        printf("fail to timer_create usec_timer\n");
        exit(-1);
    }
}

 

struct sigevent {
    int           sigev_notify;            //Notification type. 
    int           sigev_signo;            //Signal number. 
    union sigval  sigev_value;             //Signal value. 
    void         (*sigev_notify_function)(union sigval); //Notification function. 
    pthread_attr_t *sigev_notify_attributes;  //Notification attributes. 
};

sigev_notify

 sigev_notify 的取值范围如下,只有3种情况(对应的宏在<signal.h>中定义)。

SIGEV_NONE

事件发生时,什么也不做.

SIGEV_SIGNAL

事件发生时,将sigev_signo 指定的信号(A queued signal)发送给指定的进程.

SIGEV_THREAD

事件发生时,内核会(在此进程内)以sigev_notification_attributes为线程属性创建一个线程,并且让它执行sigev_notify_function

传入sigev_value作为为一个参数.

sigev_signo

 在sigev_notify = SIGEV_SIGNAL 时使用,指定信号的种别(number).

sigev_value

sigev_notify = SIGEV_THREAD 时使用,作为sigev_notify_function 的参数.

union sigval
{
    int sival_int;
    void *sival_ptr;
};  

(*sigev_notify_function)(union sigval)

函数指针(指向通知执行函数),在sigev_notify = SIGEV_THREAD 时使用, 其他情况下置为NULL.

sigev_notify_attributes

指向线程属性的指针,在sigev_notify = SIGEV_THREAD 时使用,指定创建线程的属性, 其他情况下置为NULL. 

struct itimerspec 
{
    struct timespec it_interval;  /* Timer interval(timer循环时间间隔) */
    struct timespec it_value;     /* Initial expiration(timer初次到期时间间隔) */
};
struct timespec 
{
    time_t tv_sec;        /* Seconds */
    long   tv_nsec;        /* Nanoseconds(纳秒:十亿分之一秒) */
};

编译时需要连接实时扩展库: -lrt

参考:https://blog.youkuaiyun.com/centnetHY/article/details/79695464

            http://blog.chinaunix.net/uid-317451-id-92667.html

           https://www.cnblogs.com/LubinLew/p/POSIX-DataStructure.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值