I've written a program which forks in a loop. The only thing children processes do is to increase a counter and exit, whereas a parent process waits for each of them.
My goal is to measure user and system time of parent process and all his children separately. I've succeded with parent process using times() function and struct tms. Surprisingly, the same aproach to children processes isn't working. What is the mistake that I'm doing? How to measure those times?
I've also tried getrusage() and I/it failed.
My code:
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/wait.h>
#include <sys/time.h>
#include <sys/resource.h>
#include <sys/times.h>
#include <time.h>
#ifndef COUNT
#define COUNT 100000
#endif
int counter;
int main(){
struct tms time1,time2;
times(&time1);
int count = COUNT;
pid_t pid;
while(count--){
if((pid=fork())<0){
printf("fork error\n");
} else if(pid==0){ /* child */
counter++;
_exit(0);
} else {
waitpid(pid,NULL,0); /*wait()*/
}
}
printf("COUNTER: %d\n",counter);
times(&time2);
long double clktck=sysconf(_SC_CLK_TCK);
double user=(time2.tms_utime-time1.tms_utime)/(double)clktck;
double system=(time2.tms_stime-time1.tms_stime)/(double)clktck;
double cuser=(time2.tms_cutime-time1.tms_cutime)/(double)clktck;
double csystem=(time2.tms_cstime-time1.tms_cstime)/(double)clktck;
printf("USER:%lf\nSYSTEM:%lf\n",user,system);
printf("CUSER:%lf\nCSYSTEM:%lf\n",cuser,csystem);
return 0;
}
if a call to fork() returns 0 it means that it is the child process that called the fork(). While if the return value of fork() is a positive integer, it means that the fork() was executed in the parent process and the returned positive integer is a PID of the child process.
The wait() System Call. The system call wait() is easy. wait() takes the address of an integer variable and returns the process ID of the completed process. One of the main purposes of wait() is to wait for completion of child processes.
Just use: while(wait(NULL) > 0); This ensures that you wait for ALL the child processes and only when all have returned, you move to the next instruction.
The inter communication between a child process and a parent process can be done through normal communication schemes such as pipes, sockets, message queues, shared memories.
I think the problem is that your children are executing too quickly; they don't take enough time to execute, so the sum of their time is plenty of zeros. To test this theory, I slightly changed your program:
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <sys/time.h>
#include <sys/resource.h>
#include <sys/times.h>
#include <time.h>
#ifndef COUNT
#define COUNT 100
#endif
int counter;
int main(){
struct tms time1,time2;
times(&time1);
int count = COUNT;
pid_t pid;
while(count--){
if((pid=fork())<0){
printf("fork error\n");
} else if(pid==0){ /* child */
int i;
for (i=0; i<10000; i++) {
printf("in child %i\n", getpid());
}
exit(0);
} else {
waitpid(pid,NULL,0); /*wait()*/
}
}
printf("COUNTER: %d\n",counter);
times(&time2);
printf("%lu %lu %lu %lu\n", time2.tms_utime, time2.tms_stime, time2.tms_cutime, time2.tms_cstime);
long double clktck=sysconf(_SC_CLK_TCK);
double user=(time2.tms_utime-time1.tms_utime)/(double)clktck;
double system=(time2.tms_stime-time1.tms_stime)/(double)clktck;
double cuser=(time2.tms_cutime-time1.tms_cutime)/(double)clktck;
double csystem=(time2.tms_cstime-time1.tms_cstime)/(double)clktck;
printf("USER:%lf\nSYSTEM:%lf\n",user,system);
printf("CUSER:%lf\nCSYSTEM:%lf\n",cuser,csystem);
return 0;
}
You'll see that I drastically cut down on the number of children, and made the children do some real work; 10_000
printf(... getpid())
operations. Now the times amount to something:
$ time ./times
...
in child 16181
COUNTER: 0
1 0 24 95
USER:0.010000
SYSTEM:0.000000
CUSER:0.240000
CSYSTEM:0.950000
real 0m2.234s
user 0m0.250s
sys 0m0.950s
I'm afraid your children just didn't have enough work to do to amount to anything. (Odd, sounds like parenting advice.)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With