Handle a signal & clock() & timestamp
C
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;
}