0

I want to measure the execution time of a child process. I can use times function https://linux.die.net/man/3/times. But it requires to block the parent process using wait(). On the other hand, I need to keep the parent process running in parallel to store the data being generated by the child. Once the child has exited, I want to know how much CPU time was spent in executing the child process. Something like below:

int done = FALSE; 

struct timespec ts;
struct rusage ru;
struct timeval utime;
struct timeval stime;
int main(int argc, char* argv[]){   
        pid_t pid1, pid2; int status; 
        char *args[] = {"./wp"};
        struct rusage usage; 
        int i, j,n;
        signal(SIGCHLD,reaper); 
        pid1 = fork();
        if (pid1 == 0) {            // child
            printf("Its child %d\n",getpid());      
            printf("child %d: executing target program\n", getpid()); 
            execv(argv[1], argv+1);         
        }
       n = 0;
       while (n<20) {  //parent has to do some stuff in parallel
            printf("doing something...\n"); sleep(1); 
            if (done){ // child exited
                done = FALSE;
                pid_t pid2 = wait3(&status, 0, &usage); 
                printf("...child of %d done executing.\n",getpid()); 
                printf("exit code for %d is %d\n", pid2, status); 
                if (WIFEXITED(status)) 
                    printf("The exit status is %d\n", WEXITSTATUS(status));
                utime = usage.ru_utime;
                stime = usage.ru_stime;
                printf("RUSAGE :ru_utime => %lld [sec] : %lld [usec], :ru_stime => %lld [sec] : %lld [usec] \n",
               (int64_t)utime.tv_sec, (int64_t)utime.tv_usec,
               (int64_t)stime.tv_sec, (int64_t)stime.tv_usec);
            }
            n++;
        } 
       printf("got my SIGCHLD, cleaning up!\n"); 
       signal(SIGCHLD,SIG_DFL); 
       return 0;
    }

    void reaper(int sig) { 
       done=TRUE;  //  
    } 
Jina Lee
  • 119
  • 2
  • 10
  • Just a thought -- could you implement a handler for SIGCHLD in the parent process? Record the time when you call fork()/exec() and then check the time at which the SIGCHLD handler is invoked. I haven't tried it, however -- it was just the first thing that came to mind. – Kevin Boone Sep 04 '17 at 08:31
  • That's what I have in mind. I added the skelton code in question. But the time I get in the end includes both parent and child process. How can i get separate times for both. – Jina Lee Sep 05 '17 at 01:31
  • Your belief that wait must block is incorrect. Look up the `waitpid` syscall and `WNOHANG` flag. Also, `wait3` and `wait4` functions exist which can return the usage of the single process just reaped, which is more detail than what `times` can give you (the sum over all child processes) –  Sep 05 '17 at 03:35
  • @WumpusQ.Wumbley Thanks for guiding. I have now updated my code as edited above. I believe the time obtained in rusage structure is now the child process only. How accurate will it be ...? I am having variation in the child's system time ...user time is almost fixed. Mind having a look. Thanks once again – Jina Lee Sep 05 '17 at 05:29

0 Answers0