Spring 2021
Instructors Roz Cyrus and Jerry Cain
PDF
class condition_variable_any {
public:
void wait(mutex& m);
template <typename Pred> void wait(mutex& m, Pred pred);
void notify_one();
void notify_all();
};
int main(int argc, const char *argv[]) {
size_t permits = 4;
mutex forks[5], m;
condition_variable_any cv;
thread philosophers[5];
for (size_t i = 0; i < 5; i++) {
mutex& left = forks[i], & right = forks[(i + 1) % 5];
philosophers[i] =
thread(philosopher, i, ref(left), ref(right), ref(permits), ref(cv), ref(m));
}
for (thread& p: philosophers) p.join();
return 0;
}
static void waitForPermission(size_t& permits, condition_variable_any& cv, mutex& m) {
lock_guard<mutex> lg(m);
while (permits == 0) cv.wait(m);
permits--;
}
static void grantPermission(size_t& permits, condition_variable_any& cv, mutex& m) {
lock_guard<mutex> lg(m);
permits++;
if (permits == 1) cv.notify_all();
}
static void waitForPermission(size_t& permits, condition_variable_any& cv, mutex& m) {
lock_guard<mutex> lg(m);
while (permits == 0) cv.wait(m);
permits--;
}
static void grantPermission(size_t& permits, condition_variable_any& cv, mutex& m) {
lock_guard<mutex> lg(m);
permits++;
if (permits == 1) cv.notify_all();
}
template <Predicate pred>
void condition_variable_any::wait(mutex& m, Pred pred) {
while (!pred()) wait(m);
}
static void waitForPermission(size_t& permits, condition_variable_any& cv, mutex& m) {
lock_guard<mutex> lg(m);
cv.wait(m, [&permits] { return permits > 0; });
permits--;
}
void semaphore::wait() {
lock_guard<mutex> lg(m);
cv.wait(m, [this] { return value > 0; })
value--;
}
void semaphore::signal() {
lock_guard<mutex> lg(m);
value++;
if (value == 1) cv.notify_all();
}
static void philosopher(size_t id, mutex& left, mutex& right, semaphore& permits) {
for (size_t i = 0; i < 3; i++) {
think(id);
eat(id, left, right, permits);
}
}
int main(int argc, const char *argv[]) {
semaphore permits(4);
mutex forks[5];
thread philosophers[5];
for (size_t i = 0; i < 5; i++) {
mutex& left = forks[i], & right = forks[(i + 1) % 5];
philosophers[i] = thread(philosopher, i, ref(left), ref(right), ref(permits));
}
for (thread& p: philosophers) p.join();
return 0;
}
static void eat(size_t id, mutex& left, mutex& right, semaphore& permits) {
permits.wait();
left.lock();
right.lock();
cout << oslock << id << " starts eating om nom nom nom." << endl << osunlock;
sleep_for(getEatTime());
cout << oslock << id << " all done eating." << endl << osunlock;
permits.signal();
left.unlock();
right.unlock();
}