apue学习之使用setitimer实现alarm函数

apue学习之使用setitimer实现alarm函数

1 alarm函数

#include

unsigned int alarm(unsigned int seconds);

//返回值:0或以前设置的闹钟时间的余留秒数

  参数seconds是需要设置的时钟秒数,当时间到达后,内核会产生SIGALRM信号,如果不捕捉或忽略这个信号,系统默认动作是终止调用该alarm函数的进程。
  每个进程只能有一个闹钟时间。如果在调用alarm时,之前该进程已经调用过alarm函数且还没有超时,那么返回上次设置闹钟的剩余时间,如果之前没有调用过alarm,那么返回0。

1.1 alarm函数的实例

// File Name: alarm_test.c
// Author: AlexanderGan
// Created Time: Fri 19 Jun 2020 09:34:03 AM CST

#include
#include
#include
#include
#include
#include
#include

int main(int argc, char* argv[]){
    int num = 1;
    alarm(5);
    while(1)
    {
        printf("time %d s\n",num++);
        sleep(1);
    }

  return 0 ;
}

1.2 执行情况

apue学习之使用setitimer实现alarm函数_第1张图片

2 setitimer系统调用函数

#include

int setitimer(int which, const struct itimerval *new value, struct itimerval *old value);

struct itimerval{
	struct timeval it_interval;//周期时间
	struct timeval it_value;//下一次闹钟的时间
}

struct timeval{
	time_t tv_sec;//秒s
	suseconds_t tv_usec;//微秒us
}
//参数:which:指定定时方式
		//自然定时:ITIMER_REAL → 14)SIGALRM				 		计算自然时间
		//虚拟空间计时(用户空间):ITIMER_VIRTUAL → 26)SIGVTALRM  	 只计算进程占用cpu的时间
		//运行时计时(用户+内核):ITIMER_PROF → 27)SIGPROF		 计算占用cpu及执行系统调用的时间

//返回值:成功:0;失败:-1,并设置errno

2.1 setitimer的实例

// File Name: alarm_test.c
// Author: AlexanderGan
// Created Time: Fri 19 Jun 2020 09:34:03 AM CST

#include
#include
#include
#include
#include
#include
#include
#include

void sig_handler(int sig){
        if(sig == SIGALRM)//SIGALRM的信号编号为14
        {
            printf("the SIGALRM id is : %d \n",sig);
        }
    }

int main(int argc, char* argv[]){
    int num = 1;

    struct itimerval newit = {{5,0},{2,0}};//第一次超时是2s,之后都是5s
    
    //函数名传参相当于函数指针;要在信号产生函数之前设置信号获取函数signal
    signal(SIGALRM,sig_handler);

    setitimer(ITIMER_REAL,&newit,NULL);

    while(1)
    {
        printf("time %d s\n",num++);
        sleep(1);
    }

  return 0 ;
}

2.2 执行情况

apue学习之使用setitimer实现alarm函数_第2张图片

3 仿alarm函数的实现

unsigned int i_alarm(unsigned int seconds)
{
	struct itimerval oldit, newit = {{0,0},{0,0}};
	newit.it_value.tv_sec = seconds;//将时间赋值给新时钟
	//系统调用将会查询上个闹钟的剩余时间,并写到oldit中(每个进程只有1个闹钟时间)
	setitimer(ITIMER_REAL,&newit,&oldit);
	return oldit.it_value.tv_sec;//返回上个时钟剩余秒数
}

这个函数使用起来的效果类似于alarm,略过。

你可能感兴趣的:(Linux系统编程,Computer,Systems,linux,操作系统)