哲学家就餐问题是多线程中著名的一个问题,经过前面三章的学习,可以使用多线程来模拟下这个问题了。
问题是这样的,有5个哲学家围着一个小圆餐桌坐了下来,但是桌上只有5根筷子(注意是根),每个哲学家只有全抢到左右手边的筷子才能吃东西。抢到2根筷子的哲学家过1秒后把筷子放回原位置,继续游戏。当只抢到1根,另一手的筷子被其他哲学家抢走时,就放下手中的筷子。
为了简化问题,所有哲学家都是先抢左手,在抢右手的,有兴趣可以自己去实现随机版的,差不多。
1. 问题分析
- 首先,每个哲学家都应该是一个线程;
- 其次,筷子是被共享的资源,所有每个筷子都应该被互斥量保护;
- 很明显,1个互斥量是不够保护5个资源的,至少需要5个;
- 因为需要判断能否上锁,互斥量的lock不能满足要求,而try_lock是可以的;
- 吃完等待1秒继续。
2. 代码实现
#include <iostream>
#include <exception>
#include <mutex>
#include <vector>
#include <string>
#include <algorithm>
#include <functional>
#include <thread>
#include <chrono>
std::mutex outputMutex;
class Chopsticks
{
int _i;
std::mutex _mutex;
public:
explicit Chopsticks() : _i(0) {
}
void seti(int i) {
_i = i; }
friend std::ostream& operator <<(std::ostream& out, const Chopsticks& chopsticks);
// 使用筷子就是上锁
bool use() throw(std::system_error)
{
try {
return _mutex.try_lock();
}
catch(std::system_error& e) {
throw e;
}
}
// 放下筷子就是解锁