Signal Linux system programming (eight): three time structure and timer setitime

Recommended for you: Get network issues from WhatsUp Gold. Not end users.

One, three kinds of time structure

time_t://seconds

 

struct timeval {

long tv_sec; /* seconds */

long tv_usec; /* microseconds */

};

 

struct timespec {

time_t tv_sec; /* seconds */

long tv_nsec; /* nanoseconds */

};

Two, setitimer()

Now the system many programs are no longer using the alarm call, but the use of the setitimer to set the timer, use getitimer to get the timer state,

The two call statement format is as follows:

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

Parameters:

Returns: 0 -1 on failure.

The system calls provide three timer to the process, each of them has its unique timing domain, when any one of them arrived, it sends a corresponding signal to the process, and makes the timer start. Three timer is specified by the which parameter, as shown below:

TIMER_REAL: According to the actual time, time to send the SIGALRM signal.

ITIMER_VIRTUAL: Only when the process execution is timing. Time to send a SIGVTALRM signal to the process.

ITIMER_PROF: When the process execution and system for the process execution of movements are timing. And ITIMER_VIR-TUAL is a pair of, the timer is often used in statistical process in user mode and kernel mode time. Time to send a SIGPROF signal to the process.

In the timer parameter value is used to specify the timer time, its structure is as follows:

struct itimerval {

        struct timeval it_interval; /* after the first every time */

        struct timeval it_value; /* the first call to the long time */

};

The timeval structure defines the structure as follows:

struct timeval {

        long tv_sec; /* seconds */

        long tv_usec; /* s, 1 = 1000000 microseconds*/

};

In the setitimer call, parameters of ovalue if it is not empty, the retention is the last call to set the value of the. The timer will it_value decline to 0, a signal is generated, and the it_value value is set to the value of it_interval, and then re start time, and so forth. When it_value is set to 0, the timer stops, or when it is time to expire, and it_interval is 0 when stop. The call is successful, return 0; errors, returns -1, and set the corresponding error code errno:

EFAULT: Parameters of value or ovalue is an invalid pointer.

EINVAL: The parameter which is not a ITIMER_REAL, a ITIMER_VIRT or ITIMER_PROF.

A sample:

#include <unistd.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <sys/types.h>
#include <fcntl.h>

#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <signal.h>
#include <sys/time.h>


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

void handler(int sig)
{
    printf("recv a sig=%d\n", sig);
}

int main(int argc, char *argv[])
{
    if (signal(SIGALRM, handler) == SIG_ERR)
        ERR_EXIT("signal error");

    struct timeval tv_interval = {1, 0};
    struct timeval tv_value = {5, 0};
    struct itimerval it;
    it.it_interval = tv_interval;
    it.it_value = tv_value;
    setitimer(ITIMER_REAL, &it, NULL);

    for (;;)
        pause();
    return 0;
}

Result:

QQ截图20130715202529

You can see the first send signal after 5S, then every second to send a signal

Example two: get the remaining time generating a clock signal

#include <unistd.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <sys/types.h>
#include <fcntl.h>

#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <signal.h>
#include <sys/time.h>


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


int main(int argc, char *argv[])
{
    struct timeval tv_interval = {1, 0};
    struct timeval tv_value = {1, 0};
    struct itimerval it;
    it.it_interval = tv_interval;
    it.it_value = tv_value;
    setitimer(ITIMER_REAL, &it, NULL);

    int i;
    for (i=0; i<10000; i++);

//The first way to get the rest time
    struct itimerval oit;
    setitimer(ITIMER_REAL, &it, &oit);//OIT was used to obtain the remaining time to generate a clock signal
    printf("%d %d %d %d\n", (int)oit.it_interval.tv_sec, (int)oit.it_interval.tv_usec, (int)oit.it_value.tv_sec, (int)oit.it_value.tv_usec);
//Second ways to get the remaining time
    //getitimer(ITIMER_REAL, &it);
    //printf("%d %d %d %d\n", (int)it.it_interval.tv_sec, (int)it.it_interval.tv_usec, (int)it.it_value.tv_sec, (int)it.it_value.tv_usec);

    return 0;
}

Result:

Using the first approach:

QQ截图20130715204042

In second ways: using getitimer to obtain the remaining time in not set the clock to the case

QQ截图20130715204130

The remaining time is: from the next call timer generates signal time required, here since the for cycle in less than a second after the execution, the timer can generate clock signal, so the remaining time

Example three: every second to send a SIGALRM, every 0.5 seconds to send a SIGVTALRM signal

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

void sigroutine(int signo)
{
        switch (signo) {
        case SIGALRM:
        printf("Catch a signal -- SIGALRM\n ");
        break;
        case SIGVTALRM:
        printf("Catch a signal -- SIGVTALRM\n ");
        break;
        }
        return;
}

int main()
{

       struct itimerval value,value2;
        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,NULL);


        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,NULL);

        for (;;) ;

}

Result:

QQ截图20130715205534

It is really no two SIGVTALRM a SIGALRM

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download

Posted by Wade at November 14, 2013 - 7:17 AM