The Art of Multiprocessor Programming 練習問題1と2の言い訳

The Art of Multiprocessor Programming 1章の練習問題1をやってみました。

有名な哲学者とデッドロックの話をデッドロックを回避して実装せよって問題です。
セマフォを使って常に一人だけ処理を行わないようにして、デッドロックを回避します。
コードは以下の通り。
C++を使ったのは、ただ慣れてたため。今後の練習問題ではJavaを使うかも。
練習問題2はパスします。問題を見ててもなんかピンとこないので。

#include <boost/thread.hpp>
#include <boost/bind.hpp>
#include <iostream>

const int num = 2;
int food = 10;

boost::mutex chopsticks[num];
boost::mutex food_lock;
boost::mutex counter_mutex;
int counter = 0;

void semaphore_lock()
{
   const int max = num - 1;

   while(counter >= max)
   {
      
   }
   counter_mutex.lock();
   counter++;
   counter_mutex.unlock();
}

void semaphore_unlock()
{
   counter_mutex.lock();
   counter--;
   counter_mutex.unlock();
}


void philosopher_action(int id)
{
   const int right_stick = id;
   const int left_stick = (right_stick >= (num - 1)) ? 0 : right_stick + 1;
   
   while(food > 0)
   {
      semaphore_lock();
      chopsticks[right_stick].lock();
      std::cout << id << " is holding right chopstick: " << right_stick << std::endl;
      chopsticks[left_stick].lock();
      std::cout << id << " is holding left chopstick: " << left_stick << std::endl;

      sleep(1);
      std::cout << id << " is eating" << std::endl;
      food_lock.lock();
      food--;
      food_lock.unlock();
   
      sleep(1);
      std::cout << id << " is meditating" << std::endl;

      chopsticks[right_stick].unlock();
      chopsticks[left_stick].unlock();
      semaphore_unlock();
   }
}

int main()
{
   boost::thread *t[num];

   for(int i = 0; i < num; ++i)
   {
      t[i] = new boost::thread(boost::bind(philosopher_action, i));
   }

   for(int i = 0; i < num; ++i)
   {
      t[i]->join();
   }

   return 0;
}