Programación del sistema Linux 47 señales-setitimer (), se prefiere setitimer () para cronometraje

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

SYNOPSIS
       #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);

Función descriptiva:

Parámetro 1 que

  TIMER_REAL    以系统真实的时间来计算,时间到了 它送出SIGALRM信号。可以代替 alarm

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

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

Estructura relacionada:

   struct itimerval {
           struct timeval it_interval; /* Interval for periodic timer */ 设置的定时器时间
           struct timeval it_value;    /* Time until next expiration */ 定时器剩余时间
       };

       struct timeval {
           time_t      tv_sec;         /* seconds */
           suseconds_t tv_usec;        /* microseconds */
       };

El mecanismo de trabajo de settimer es contar primero it_value y activar la señal cuando it_value es cero. Luego restablezca a it_interval. Continúe la cuenta regresiva hasta it_value. Sigue así.
Basado en este mecanismo. setitimer se puede utilizar para retrasar la ejecución o para ejecutar con regularidad.
Si it_value es 0, la señal no se disparará, por lo que para poder disparar la señal, it_value debe ser mayor que 0; asumiendo que it_interval es cero, solo se retrasará. No se cronometrará (es decir, la señal solo se activará una vez).

Parámetro 2 new_value: El
parámetro se usa para configurar el temporizador, it_interval es el intervalo de tiempo, it_value es el tiempo de retardo, si se selecciona el reloj TIMER_REAL, significa que después de que el método setitimer se llama con éxito, la señal SIGALRM se activa una vez después it_value se retrasa. La señal SIGALRM se activa una vez cada it_interval.

Parámetro 3 old_value : generalmente no se usa, establecido en NULL, se usa para almacenar el valor new_value establecido en la última llamada de setitimer.

En caso de éxito, se devuelve cero. En caso de error, se devuelve -1 y errno se establece adecuadamente

Experimento, experimento de control de flujo con balde con fugas, realizado con setitimer ()

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#include <signal.h>
#include <sys/time.h>

#define BUFSIZE 10

static volatile int loop = 0;

static void alrm_handler(int s)
{
	//alarm(1);
	loop = 1;
}

int main(int argc,char *argv[])
{
	int sfd,dfd=1;
	char buf[BUFSIZE];
	int len,ret,pos;
	struct itimerval itv;
	if(argc < 2)
	{
		fprintf(stderr,"Usage:%s <src_file> <dest_file>\n",argv[0]);
		exit(1);
	}
	

	signal(SIGALRM,alrm_handler);
	//alarm(1);
	itv.it_interval.tv_sec = 1;
	itv.it_interval.tv_usec = 0;
	itv.it_value.tv_sec = 1;
	itv.it_value.tv_usec = 1;

	if(setitimer(ITIMER_REAL,&itv,NULL) < 0)
	{
		perror("setitimer()");
		exit(1);
	}

	do
	{
		sfd = open(argv[1],O_RDONLY);
		if(sfd < 0)
		{
			if(errno != EINTR)//signal
			{
				perror("open()");
				exit(1);	
			}

		}
	}while(sfd < 0);


	while(1)
	{

		while(!loop)
			pause();
		
		loop = 0;

		while((len = read(sfd,buf,BUFSIZE)) < 0)
		{	if(errno == EINTR)//signal
				continue;
			perror("read()");
			break;
		}
		if(len == 0)
			break;

		//确保写进去 len 个字节
		pos = 0;
		while(len > 0)
		{
			ret = write(dfd,buf+pos,len);
			if(ret < 0)
			{
				if(errno == EINTR) //signal
					continue;
				perror("write()");
				exit(1);
			}
			pos += ret;
			len -= ret;
		}

	}
	
	close(sfd);
		
}

Supongo que te gusta

Origin blog.csdn.net/LinuxArmbiggod/article/details/114072825
Recomendado
Clasificación