Spring 2021
Instructors Roz Cyrus and Jerry Cain
PDF
static void eat(size_t id, mutex& left, mutex& right) {
left.lock();
sleep_for(5000); // artificially force off the processor
right.lock();
cout << oslock << id << " starts eating om nom nom nom." << endl << osunlock;
sleep_for(getEatTime());
cout << oslock << id << " all done eating." << endl << osunlock;
left.unlock();
right.unlock();
}
static void philosopher(size_t id, mutex& left, mutex& right) {
for (size_t i = 0; i < 3; i++) {
think(id); // not implemented because thinking is easy
eat(id, left, right);
}
}
int main(int argc, const char *argv[]) {
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));
}
for (thread& p: philosophers) p.join();
return 0;
}
int main(int argc, const char *argv[]) {
size_t permits = 4;
mutex forks[5], permitsLock;
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(permitsLock));
}
for (thread& p: philosophers) p.join();
return 0;
}
static void eat(size_t id, mutex& left, mutex& right, size_t& permits, mutex& permitsLock) {
waitForPermission(permits, permitsLock); // on next slide
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;
grantPermission(permits, permitsLock); // on next slide
left.unlock(); right.unlock();
}
static void philosopher(size_t id, mutex& left, mutex& right,
size_t& permits, mutex& permitsLock) {
for (size_t i = 0; i < kNumMeals; i++) {
think(id);
eat(id, left, right, permits, permitsLock);
}
}
static void waitForPermission(size_t& permits, mutex& permitsLock) {
while (true) {
permitsLock.lock();
if (permits > 0) break;
permitsLock.unlock();
sleep_for(10);
}
permits--;
permitsLock.unlock();
}
static void grantPermission(size_t& permits, mutex& permitsLock) {
permitsLock.lock();
permits++;
permitsLock.unlock();
}
class condition_variable_any {
public:
void wait(mutex& m);
template <typename Pred> void wait(mutex& m, Pred pred);
void notify_one();
void notify_all();
};