餐饮哲学家问题(dpp)的此解决方案如何运作?互斥量和信号量

时间:2019-06-13 21:16:02

标签: c++ multithreading mutex semaphore dining-philosopher

我正在尝试解决 用餐哲学家的问题 问题: https://en.wikipedia.org/wiki/Dining_philosophers_problem),我找到了带有代码的解决方案下面。解决方案使用信号量和一个互斥量。我自己实现了繁忙的等待简单信号量,因为C ++不提供信号量。我无法理解services.AddTransient<IBot, DialogBot<MainDialog>>();take_forks函数中互斥锁的目的是什么。

我试图找到问题的答案,但没有。所以我问堆栈溢出。

我的问题是:

  1. put_forkstake_forks函数中互斥锁的目的是什么? (什么会导致比赛条件发生?)
  2. 此解决方案的名称是什么?这是仲裁解决方案吗?

这是我的代码

put_forks

我希望互斥锁必须在#include <mutex> #include <thread> #define N 5 #define THINKING 0 #define HUNGRY 1 #define EATING 2 typedef int sem_t; void sem_up(sem_t* semaphore) { (*semaphore)++; } void sem_down(sem_t* semaphore) { while (*semaphore == 0) {} (*semaphore)--; } std::mutex mutualExclusion; char philosopherState[N] = {THINKING}; sem_t philosopherSemaphore[N] = { 0 }; void test(short i) { if (philosopherState[i] == HUNGRY && philosopherState[(i + 1) % N] != EATING && philosopherState[(i + N - 1) % N] != EATING) { philosopherState[i] = EATING; sem_up(&philosopherSemaphore[i]); } } void think(short p) { //some code } void eat() { //some code } void take_forks(short i) { ::mutualExclusion.lock(); philosopherState[i] = HUNGRY; test(i); ::mutualExclusion.unlock(); sem_down(&philosopherSemaphore[i]); } void put_forks(short i) { ::mutualExclusion.lock(); philosopherState[i] = THINKING; test((i + 1) % N); test((i + N - 1) % N); ::mutualExclusion.unlock(); } void philosopher(short i) { while (1) { think(); take_forks(i); eat(); put_forks(i); } } 函数中,因为这是我发现竞争状况的唯一原因。

任何答案和建议都值得赞赏!谢谢!

1 个答案:

答案 0 :(得分:0)

我找到了问题的答案。

此解决方案由A. Tanenbaum提出,是几种称为仲裁的解决方案之一。通过这种方法,可以保证哲学家只能通过引入 仲裁器(例如侍者)来选择 叉子或不叉 。要拿起叉子,哲学家必须征得服务员的允许。在每次拿起两个叉子之前,服务生一次只允许一位哲学家允许。服务员可以实现为互斥体。因此,检查和更新数组的操作是原子的,并且可以保证对fork的独占访问。 (这就是互斥的目的)


几个参考文献