I'm doing a school assignment that basically involves creating a couple of child processes which approximate pi
and write their results to a text file with the same name as the child process id. The parent process then waits for all the children and calculates the average approximation for pi
from the values stored in the text files.
Things work pretty good, but every now and then (about 10% of the times I execute the program) wait(NULL)
returns -1 and errno
indicates Interrupted system call
for one of the child processes. I have no idea why this happens seemingly randomly.
In the code below, MonteCarlo
is a custom class that deals with the approximation of Pi.
#include <random>
#include <iostream>
#include <iomanip>
#include <fstream>
#include <unistd.h>
#include "MonteCarlo.h"
int main(int argc,char** argv){
int approximationProcessCount = 10;
int approximationRandomCount = 1000;
for(int i=0; i<approximationProcessCount; i++){
//pidArray[i] = fork();
pid_t pid = fork();
if( pid == -1 ){
// Fork error
perror("Fork error");
}
else if( pid == 0 ){
// Child process
MonteCarlo mc(approximationRandomCount);
std::string filename(std::to_string(getpid()) + ".txt");
std::ofstream fs( filename );
if( !fs ){
std::cerr << "Cannot open '" << filename << "' for writing." << std::endl;
return 1;
}
fs << mc.approximate();
fs.flush();
fs.close();
return 0;
}
else{
// Parent process
}
}
// Parent process
double averageApproximation = 0.0;
for(int i=0; i<approximationProcessCount; i++){
pid_t childPid = wait(NULL);
if( childPid == -1 ){
perror( std::string("Error when waiting for child process [-1] (i=" + std::to_string(i) + ")").c_str());
continue;
}
else if( childPid == 0 ){
perror( std::string("Error when waiting for child process [0] (i=" + std::to_string(i) + ")").c_str());
continue;
}
std::string filename(std::to_string(childPid) + ".txt");
std::ifstream fs( filename );
if( !fs ){
std::cerr << "Cannot open '" << filename << "' for reading." << std::endl;
return 1;
}
double approximation;
fs >> approximation;
fs.close();
remove(filename.c_str());
// Calculate average "on the fly"
averageApproximation += (approximation - averageApproximation)/(i+1);
}
std::cout << "Average approximation of Pi = " << averageApproximation << std::endl;
}
When I encounter the "error", I get the following output (i
varies):
Error when waiting for child process [-1] (i=9): Interrupted system call
Average approximation of Pi = 3.14444
I'm running this in XCode on Mac OSx El Capitan.