Finish the code below. It should start N examples of makePrimes. It should start 1 example of print. N comes from the command line as the first argument. Basically, this means to finish main() to start and join threads, and to make Buffer class that is a thread safe ring buffer that you wrote yourself. You should not have to change any of my code below. Atomics of any sort are forbidden. Use must use mutexes, locks, notify, and wait. The program should search for primes from 100,000,001 to 100,001,001. Hint: You cannot call exit(0) when killing a program with running threads. But you can call _exit(0). Hint: When a producer thread has searched it's range, it might put -1 onto the queue. When the consumer gets enough -1, it knows that every producer has finished. Hint: compile like this g++ foo.cc -lpthread -o foo Hint: You can produce a sorted list like this ./answer | sort -n Due Wed Oct 12th. -10% per workday late. ============================================================== #include // cout #include // thread #include // mutex, unique_lock #include // condition_variable #include // usleep #include Buffer buffer; bool isPrime(int maybe) { if (maybe % 2 == 0) return false; for(int i = 3; i < maybe; i+=2) if (maybe % i == 0) return false; return true; } void makePrimes(int start, int stop) { for(int i = start; i < stop; i++) { if (isPrime(i)) { int s = rand() % 1000; usleep(s); buffer.put(i); } } buffer.put(-1); } void print(int instances) { int stopCounter = 0; while (1) { int value = 0; int s = rand() % 100; usleep(s); value = buffer.get(); if(value == -1) { stopCounter = stopCounter + 1; if(stopCounter == instances) { _exit(0); } } if(value != -1) cout << "Prime " << value << endl; } } int main (int argc, char *argv[]) { }