Handle a signal & clock() & timestamp

C

Library: POSIX

Standard C's sleep() only provides one-second resolution, so the POSIX usleep() function is used here. (POSIX is not needed for the actual signal handling part.)

#include <stdio.h>
#include <stdlib.h> // for exit()
#include <signal.h>
#include <time.h> // for clock()
#include <unistd.h> // for POSIX usleep()
 
volatile sig_atomic_t gotint = 0;
 
void handleSigint() {
/*
* Signal safety: It is not safe to call clock(), printf(),
* or exit() inside a signal handler. Instead, we set a flag.
*/
gotint = 1;
}
 
int main() {
clock_t startTime = clock();
signal(SIGINT, handleSigint);
int i=0;
for (;;) {
if (gotint)
break;
usleep(500000);
if (gotint)
break;
printf("%d\n", ++i);
}
clock_t endTime = clock();
double td = (endTime - startTime) / (double)CLOCKS_PER_SEC;
printf("Program has run for %5.3f seconds\n", td);
return 0;
}
Output:
1
2
3
Program has run for 1.953 seconds

 

copyright

https://rosettacode.org/wiki/Handle_a_signal#C

 

clock_gettime

#include <stdio.h>
#include <stdlib.h>    // for exit()

#include <stdint.h>
#include <signal.h>
#include <unistd.h>    // for POSIX usleep()
#include <time.h>

/**
 * @return milliseconds
 */
double get_now_time() {
  struct timespec spec;
  if (clock_gettime(1, &spec) == -1) { /* 1 is CLOCK_MONOTONIC */
    abort();
  }

  return spec.tv_sec * 1000 + spec.tv_nsec / 1e6;
}
 
volatile sig_atomic_t gotint = 0;
 
void handleSigint() {
    /*
     * Signal safety: It is not safe to call clock(), printf(),
     * or exit() inside a signal handler. Instead, we set a flag.
     */
    gotint = 1;
}
 
int main() {

    double time_in_mill1 = get_now_time();

    signal(SIGINT, handleSigint);
    int i=0;
    for (;;) {
        if (gotint)
            break;
        usleep(1000*1000);
        if (gotint)
            break;
    printf("%d\n", ++i);
    }

    double time_in_mill2 = get_now_time();

    printf("Program has run for %5.3f seconds\n", (time_in_mill2 - time_in_mill1)/1000);
    return 0;
}

 

gettimeofday

#include <stdio.h>
#include <stdlib.h>    // for exit()
#include <signal.h>
#include <unistd.h>    // for POSIX usleep()

#include <sys/time.h>
#include <stdlib.h>
#include <stdint.h>

/**
 * @return milliseconds
 */
double get_now_time() {
    struct timeval te;
    gettimeofday(&te, NULL); // get current time
    double milliseconds = te.tv_sec*1000LL + te.tv_usec/1000; // calculate milliseconds
    return milliseconds;
}
 
volatile sig_atomic_t gotint = 0;
 
void handleSigint() {
    /*
     * Signal safety: It is not safe to call clock(), printf(),
     * or exit() inside a signal handler. Instead, we set a flag.
     */
    gotint = 1;
}
 
int main() {

    double time_in_mill1 = get_now_time();

    signal(SIGINT, handleSigint);
    int i=0;
    for (;;) {
        if (gotint)
            break;
        usleep(1000*1000);
        if (gotint)
            break;
    printf("%d\n", ++i);
    }

    double time_in_mill2 = get_now_time();

    printf("Program has run for %5.3f seconds\n", (time_in_mill2 - time_in_mill1)/1000);
    return 0;
}

 

C11 timespec_get

It returns up to nanoseconds, rounded to the resolution of the implementation.

It is already implemented in Ubuntu 15.10. API looks the same as the POSIX clock_gettime.

#include <time.h>
struct timespec ts;
timespec_get(&ts, TIME_UTC);
struct timespec {
    time_t   tv_sec;        /* seconds */
    long     tv_nsec;       /* nanoseconds */
};


This version need not math library and checked the return value of clock_gettime().

#include <time.h>
#include <stdlib.h>
#include <stdint.h>

/**
 * @return milliseconds
 */
uint64_t get_now_time() {
  struct timespec spec;
  if (clock_gettime(1, &spec) == -1) { /* 1 is CLOCK_MONOTONIC */
    abort();
  }

  return spec.tv_sec * 1000 + spec.tv_nsec / 1e6;
}


Following is the util function to get current timestamp in milliseconds:

#include <sys/time.h>

long long current_timestamp() {
    struct timeval te; 
    gettimeofday(&te, NULL); // get current time
    long long milliseconds = te.tv_sec*1000LL + te.tv_usec/1000; // calculate milliseconds
    // printf("milliseconds: %lld\n", milliseconds);
    return milliseconds;
}
 

other signal

void __sigroutine( int p_iSigNum )
{
    switch( p_iSigNum )
    {
    case SIGHUP:
    case SIGINT:
    case SIGQUIT:
    case SIGTERM:
        _bStop = true;
        printf("recv signal %d\n", p_iSigNum);
        break;

    default:
        break;
    }
}

bool __init_capture()
{
    if( SIG_ERR == signal( SIGHUP, __sigroutine ) )
    {
        printf("signal SIGHUP failed\n");
        return false;
    }

    if( SIG_ERR == signal( SIGINT, __sigroutine ) )
    {
        printf("signal SIGINT failed\n");
        return false;
    }

    if( SIG_ERR == signal( SIGQUIT, __sigroutine ) )
    {
        printf("signal SIGQUIT failed\n");
        return false;
    }

    if( SIG_ERR == signal( SIGTERM, __sigroutine ) )
    {
        printf("signal SIGTERM failed\n");
        return false;
    }

    return true;
}

 

posted @ 2020-11-26 01:06  dong1  阅读(73)  评论(0编辑  收藏  举报