0

I would like to measure the CPU and User time passed between starting a process and sending SIGINT signal using C times function.

However, on print I just get 0. Can't see the problem..

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

struct tms time_start;
struct tms time_end;

clock_t start;
clock_t end; 

void handle() { 
    times(&time_end);
    end = time_end.tms_stime;
} 

int main(int argc, char *argv[]) { 

    signal(SIGINT, handle);
    times(&time_start);
    start = time_start.tms_utime;
    pause(); 
    printf("end: %ld, start: %ld\n", (long) end, (long) start);

    return 0;
}

This is the output I get:

k@sc:dir$ ./my_time
^Cend: 0, start: 0
Rob
  • 14,746
  • 28
  • 47
  • 65
TMOTTM
  • 3,286
  • 6
  • 32
  • 63
  • `end` has type `clock_t`, you're printing a `long` with `"%ld"`. I'd convert ... `printf("%ld\n", (long)end);` ... "clock_t shall be an integer or real-floating type" – pmg May 26 '20 at 09:30
  • 1
    @TMOTTM Could you please remove line numbers from your code snippet? Could you please include the relevant `#include` headers in your source and remove the additional empty lines? Side note: calling `printf` from a signal handler is not allowed. – KamilCuk May 26 '20 at 10:11
  • 1
    I adjusted it and pasted a second version – TMOTTM May 26 '20 at 10:31

1 Answers1

0

on print I just get 0. Can't see the problem..

The tms_stime is the CPU time spend in the kernel on behalf of the process. pause() is doing nothing, so it doesn't count for CPU time, signal and times are not computationally demanding functions - your program is doing nothing. Do some I/O operations, get that kernel to work to see some changes in times.

For example the following program reads 400000000 bytes from /dev/urandom:

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

struct tms time_end;

void handle() {
    times(&time_end);
}

int main(int argc, char *argv[]) {
    signal(SIGINT, handle);

    // read from urandom so that kernel has to generate randomness
    FILE *f = fopen("/dev/urandom", "r");
    for (int i = 0; i < 20000000; ++i) {
        char buf[20];
        fread(buf, sizeof(buf), 1, f);
    }
    fclose(f);

    pause();

    printf("tms_stime = %ld\n", (long)time_end.tms_stime);
    return 0;
}

Saved as 1.c file and executed on my system in shell outputs:

$ sh -c 'gcc 1.c ; ./a.out & child=$!; sleep 2; kill -INT $child ; wait'
tms_stime = 127

On linux there is also CLOCK_PROCESS_CPUTIME_ID you might be interested in.

KamilCuk
  • 120,984
  • 8
  • 59
  • 111