4508l3 Listing 3. Allocating Threads int main (int argc, char *argv[]){ int num_threads(2); // were we called properly? if (argc<3) usage(argv[0]); if (argc==4) num_threads=atol(argv[3]); try { pthread_t *t_id=new pthread_t[num_threads]; CountPrimes **counter= new CountPrimes*[num_threads]; // start up the threads long start(atol(argv[1])); long stop(atol(argv[2])); long incr((stop-start)/num_threads); for (int i=0; istop?stop:start+incr); start+=incr+1; pthread_create(&t_id[i],NULL, counter[i]->entry,counter[i]); } // now wait for the results long count=0; for (int i=0; i(return_val)); delete reinterpret_cast(return_val); } for (int i=0; i1){ cout << "There were " << count; cout << " primes." << endl; } else{ cout << "There was " << count; cout << " prime." << endl; } } catch (range_error e){ cout << "Exception: " << e.what() << endl; exit(EXIT_FAILURE); } return EXIT_SUCCESS; }