#include #include // fork and wait #include #include #include // for the memory mapping #include #include #include using namespace std; long double Pi(int iterations); const string MEM_NAME{"BENNETT_PI"}; int main(int argc, char * argv[]) { int procs{10}; int iterations {1'000'000}; if (argc > 1) { int tmp{stoi(argv[1])}; if (tmp > 1 and tmp < 1000) { procs = tmp; } } if (argc > 2) { int tmp{stoi(argv[2])}; if (tmp > 1) { iterations = tmp; } } int flags{O_RDWR | O_CREAT | O_TRUNC}; int mode{S_IRUSR | S_IWUSR}; // create the shared memory segment int fd = shm_open(MEM_NAME.c_str(), flags, mode); if (fd == -1) { perror("shm_open:"); return 1; } // make it the right size if(-1 == ftruncate(fd, sizeof(long double) * procs)) { perror("ftruncate:"); shm_unlink(MEM_NAME.c_str()); return 1; } // open it as an array long double * results{ static_cast( mmap(nullptr, sizeof(long double)*procs, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0) ) }; if (results == nullptr) { perror("mmap:"); shm_unlink(MEM_NAME.c_str()); return 1; } shm_unlink(MEM_NAME.c_str()); cout << "Computing pi with " << procs << " processes for " << iterations << " iterations." << endl; // compute the value on each child // note we could compute on the parent as well, // but i would like to keep it simple for(int i = 0; i < procs; ++i) { if (fork() == 0) { srand(time(nullptr)*(i+1)); long double myPi {Pi(iterations)}; cout << " process " << i << " got " << myPi << endl; results[i] = myPi; return 0; } } // wait for all of the children to exit for(int i = 0; i < procs; ++i) { wait(nullptr); } cout << endl << endl; cout << "The children have exited" << endl; cout << endl; // compute the average long double pi{0}; for(int i = 0; i < procs; ++i) { cout << results[i] << " from child " << i << endl; pi += results[i]; } pi /= static_cast (procs); cout << "The final pi is " << pi << endl; return (0); } long double Pi(int iterations){ long double pi{0}; long long count{0}; long double x, y; for(int i = 0 ; i < iterations; ++i) { x = rand() / static_cast(RAND_MAX); y = rand() / static_cast(RAND_MAX); if (x*x + y*y <= 1) { ++count; } } return static_cast(count) / static_cast(iterations) * 4; }