CS 3400: Sharks and divers
Two small stretches of coral reef are right next to each other, and both have a lot of tasty fish. Sharks love feeding in these reefs, and divers also love fishing in them. The two groups have agreed to a deal where divers can fish in the reefs so long as the sharks never see the divers doing it. If a shark ever sees a diver in one of the reefs, it must eat the diver or be shamed by all of its shark friends.
There are two reefs, six sharks, and two divers.
In this assignment, you will write a program with nine threads: one for each shark, one for each diver, and the main thread that sets everything up.
Your job is to synchronize the sharks and the divers. No diver should ever get eaten. You can assume that if a shark is feeding in either reef, a diver attempting to fish in the other reef will be spotted and eaten. When sharks are not feeding, they will not see divers fishing. You may not starve either the sharks or the divers. Only one shark or diver may fish in a given reef at any one time.
You may use either semaphores, or locks and condition variables to synchronize your program. Both are defined in the POSIX threads library.
To use a semaphore:
// create a semaphore sem_t sem; int s = sem_init(&sem, 0, initial_count); assert(s == 0); // P/down/wait/acquire a semaphore s = sem_wait(&sem); assert(s == 0); // V/up/post/release a semaphore s = sem_post(&sem); assert(s == 0);
To use locks and condition variables:
// create a lock pthread_mutex_t mutex; int s = pthread_mutex_init(&mutex, NULL); assert(s == 0); // acquire a lock s = pthread_mutex_lock(&mutex); assert(s == 0); // release a lock s = pthread_mutex_unlock(&mutex); assert(s == 0); // create a condition variable pthread_cond_t condition; s = pthread_cond_init(&condition, NULL); assert(s == 0); // wait on a condition variable s = pthread_cond_wait(&condition, &mutex); assert(s == 0); // notify on a condition variable s = pthread_cond_signal(&condition); assert(s == 0); // notify all on a condition variable s = pthread_cond_broadcast(&condition); assert(s == 0);
You should not use any other methods or options for either system, including timeouts, non-blocking acquires, etc.
I have supplied code in
sharks.c to get you started:
Along with a simple
Makefile to build it:
It spawns a thread for each shark and each diver. It then lets them run for a while (60 seconds by default), and then shuts everything down.
The code has two global arrays; one with a spot for each shark, and
one with a spot for each diver. Whenever a shark or diver starts
fishing, it should set its slot to
true and call
Likewise, when it stops fishing, it should set its slot to
report() again. Note that
report() is not synchronized,
so it may occasionally print bogus data, but most of the time it
should give you a short summary of the current state of the reefs.
Your job is to create whatever synchronization variables you need
(semaphores, locks, condition variables, integers, etc.) as global
variables (you can initialize them when you create them), and then
finish the implementations of
Last Updated 09/07/2018