Is printing interrupted?

I have a program that generates a random number, n, and then loop n times.

At each iteration, it randomizes the sleeptime value and calls fork. The child process falls asleep in sleeptime seconds, and then exits with the value of the index variable.

Then the parent loops again, waiting for each process to complete. As each process ends, I try to output the pid and childid of the process, but I ran into difficulties in this. Folders are printed in order, and childid remains at 0.

What am I doing wrong?

 int main(int argc, char* argv[]) { // Wire up the timer long time = elapsedTime(0); /* Generate a random number between MINFORKS and MAXFORKS */ unsigned int seed = generateSeed(0); int n = rand_r(&seed) % MAXFORKS + MINFORKS-1; /* Log next step */ time = elapsedTime(1); printf("%li: Number of forks = %i\n", time, n); /* Hang on to the PIDs so we can wait for them after forking */ pid_t *PIDs = (pid_t *)(malloc(sizeof(*PIDs)*n)); /* Fork n times */ for (int i = 0; i < n ; i++) { /* Call fork() and retain the returned identifier */ pid_t processIdentifier = fork(); /* Randomize the child sleep time */ seed = generateSeed(0); int sleeptime = rand_r(&seed) % MAXPAUSE + MINPAUSE; /* Check for errors */ if (processIdentifier == -1) { printf("Error: %i", errno); } if (!processIdentifier) { /* We're in the child process, * sleep and then exit with * i as the error code. */ usleep(sleeptime); _exit(i); } else { /* We're in the parent: * Store the PID and * print out the results. */ PIDs[i] = processIdentifier; time = elapsedTime(1); printf("%li: Child %i, pid = %i, forked, waits %i usec\n", time, i, processIdentifier, sleeptime); } } /* Log next step */ time = elapsedTime(1); printf("%li: Finished forking, going to wait.\n", time); /* * Loop through the processes and wait for them * to terminate. Then print the childid, and the * the pid. */ for (int i = 0; i < n; i++) { /* Get the PID we want to track */ pid_t pid = PIDs[i]; /* Wait for the child process * and grab it status info */ int status = NULL; waitpid(pid, &status, 0); int childid = -1; if(WIFEXITED(status)) { childid = WTERMSIG(status); } /* Log the results */ time = elapsedTime(1); printf("%li: Child %i, pid = %i, terminated\n", time, childid, pid); } /* All done! */ time = elapsedTime(1); printf("All done. It only took %li milliseconds!", time); } 

Disclaimer, this is homework (the link here may disappear at any time) , but I have already done almost all of this. I just have problems with this aspect.

+8
c process fork waitpid
source share
2 answers

Your code expects pids in the order in which you provide them in your successive waitpid() calls. If, instead of -1 you pass -1 as the first parameter instead of waitpid() (or if you just call wait() ), you will get the first child that the kernel tells you about, and not the one you specifically asked to be notified about. Check the return value to see what it was (or an error occurred).

childid remains 0 because you are WTERMSIG from the wait state, not WEXITSTATUS .

+4
source share
 for (int i = 0; i < n; i++) { pid_t pid = PIDs[i]; int status = NULL; waitpid(pid, &status, 0); 

So, first he waits for the completion of the first process, and then prints information from this process.
He then waits for the completion of the second process, and then prints information from this process.
Then he waits for the completion of the third process ...

And you wonder why they are being reported in order?

pass -1 to waitpid , and this page says that it will make it wait for any child thread instead of a specific thread.

Also, before printing, you have int childid = -1; . I do not know why.

+2
source share

All Articles