/* primes_slave.cc This program works together with primes_master to count the number of primes between 1 and some specified upper limit. This is a slave program, which is started by the master program. It should not be started directly by the user. */ #include #include #include int main() { /* Initialize PVM by calling pvm_mytid (even though I won't need to use tid except for the error check. */ int tid = pvm_mytid(); if (tid < 0) { cout << "Error: Can't create pvm task. PVM not running?\n"; exit(1); } int parent = pvm_parent(); // This is the TID of the master program. // The slave will send results to this TID. pvm_recv(-1,1); // Receive a message from any task (in fact, from // from the master program) with message id 1. // (The message id's are just used as an error check. // If messages aren't received in the right order, // the program will fail.) int limits[2]; // The first message is a range of values. This program // should find all the prime numbers in the range // limits[0] <= x <= limits[1]. It sends this list // back to the master. pvm_upkint(limits,2,1); // Get the limits from the message. int ct = limits[1] - limits[0] + 1; // Number of integers to check. if (ct > 0) { int p[ct]; // Will hold the prime numbers that are found. int num = 0; // Number of primes found. for (int i = 0; i < ct; i++) { int n = limits[0] + i; // Number to be checked for primality. int s = (int)(sqrt(n) + 0.1); bool prime = true; for (int j = 2; j <= s; j++) { if (n % j == 0) { prime = false; // n is evenly divisible by j, so is not prime. break; } } if (prime) { // Add n to the list of primes. p[num] = n; num++; } } pvm_initsend(PvmDataRaw); pvm_pkint(&num,1,1); if (num > 0) pvm_pkint(p,num,1); pvm_send(parent,2); // Send the list to parent with message id 2. } else { // There is nothhing to do, but send back a 0 as a response, // since the master requires an answer from each slave. int num = 0; pvm_initsend(PvmDataRaw); pvm_pkint(&num,1,1); pvm_send(parent,2); } pvm_recv(-1,3); // The next message will be a list of prime numbers. pvm_upkint(&ct,1,1); // ct is the number of primes in the list. int primes[ct]; // An array to hold the primes. pvm_upkint(primes,ct,1); pvm_recv(-1,4); // The final message is a range of numbers. This // program must count the number of primes in the // assigned range. pvm_upkint(limits,2,1); // Get the range of numbers to be checked. int primect = 0; // Number of primes found. for (int i = limits[0]; i <= limits[1]; i++) { // Check whether i is prime. bool prime = true; int s = (int)(sqrt(i) + 0.1); for (int j = 0; j < ct && primes[j] <= s; j++) { if (i % primes[j] == 0) { prime = false; break; } } if (prime) primect++; } pvm_initsend(PvmDataRaw); pvm_pkint(&primect,1,1); pvm_send(parent,5); // Send number of primes found to the master program. pvm_exit(); }