changeset 21:e47640fea982

c++: update philosopher
author Jordi Gutiérrez Hermoso <jordigh@octave.org>
date Fri, 17 Apr 2015 15:41:49 -0400
parents 2b8cbff9f9ce
children 7a1528b6afdf
files c++/philosopher/Makefile c++/philosopher/main.c++ c++/philosopher/philosopher.c++ c++/philosopher/philosopher.h++ c++/philosopher/philsopher.h++
diffstat 4 files changed, 150 insertions(+), 3 deletions(-) [+]
line wrap: on
line diff
new file mode 100644
--- /dev/null
+++ b/c++/philosopher/Makefile
@@ -0,0 +1,10 @@
+.SUFFIXES : .c++ .o
+
+.c++.o:
+	g++ -c $< 
+
+object = philosopher.o main.o
+
+philo: $(object)
+	g++ -std=c++0x $(object) -o philo -lboost_thread
+
new file mode 100644
--- /dev/null
+++ b/c++/philosopher/main.c++
@@ -0,0 +1,20 @@
+#include <iostream>
+#include <vector>
+#include <boost/thread.hpp>
+#include "philosopher.h++"
+
+int main()
+{
+  using namespace std;
+  const int numphilosoph = 5;
+  boost::mutex chopstick;
+  vector<philosopher> philosophers;
+  for(size_t i = 0; i < numphilosoph; i++)
+  {
+    philosophers.push_back( philosopher(i,
+                                        chopstick,
+                                        chopstick));
+    philosophers[i].begin();
+  }
+}
+
--- a/c++/philosopher/philosopher.c++
+++ b/c++/philosopher/philosopher.c++
@@ -1,2 +1,89 @@
 #include "philosopher.h++"
+#include <boost/bind.hpp>
 
+philosopher::philosopher(int id_i,
+                         boost::mutex& left_i,
+                         boost::mutex& right_i)
+  : id(id_i), left(left_i), right(right_i)
+{
+  s = thinking;
+  bellyfull = ( double(rand() % 10) + 10)/100;
+  full = false;
+  starved = false;
+  action = boost::thread(boost::bind(&philosopher::loop, this));
+  hunger = boost::thread(boost::bind(&philosopher::hungry, this));
+}
+
+void philosopher::busy(int loops)
+{
+  for(size_t i = 0; i < loops; i++)
+  {
+    int t = rand() % 1000;
+    boost::this_thread::sleep(boost::posix_time::milliseconds(t));
+  }
+}
+
+void philosopher::eat()
+{
+  s = eating;
+  int mouthfuls = rand() % 5 + 1;
+  for(size_t i = 0; i < mouthfuls; i++)
+  {
+    double fill = (double(rand() % 5) + 1)/100;
+    {
+      bellyfull += fill;
+      if(bellyfull >= 1.00)
+      {
+        full = true;
+        break;
+      }
+    }
+    busy();
+  }
+}
+
+void philosopher::think()
+{
+  s = thinking;
+  int thoughts = rand() %5 + 1;
+  for(size_t i = 0; i < thoughts; i++)
+  {
+    busy();
+  }
+}
+
+void philosopher::hungry()
+{
+  while(not starved and not full)
+  {
+    busy(3);
+    double bellyempty = ( double(rand() % 10) + 10)/100;
+    {
+      bellyfull -= bellyempty;
+      if(bellyfull <= 0)
+        starved = true;
+    }
+  }
+}
+
+void philosopher::loop()
+{
+  while(not full and not starved)
+  {
+    think();
+    {
+      busy();
+      boost::mutex::scoped_lock(left);
+      busy();
+      boost::mutex::scoped_lock(right);
+
+      eat();
+    }
+  }
+}
+
+void philosopher::begin()
+{
+  action.join();
+  hunger.join();
+}
rename from c++/philosopher/philsopher.h++
rename to c++/philosopher/philosopher.h++
--- a/c++/philosopher/philsopher.h++
+++ b/c++/philosopher/philosopher.h++
@@ -1,6 +1,36 @@
-#ifndef __philosopher_hpp__
-#define __philosopher_hpp__
+#include <boost/thread.hpp>
+#include <string>
 
 
+enum state
+{
+  thinking,
+  eating
+};
 
-#endif //__philosopher_hpp__
+class philosopher
+{
+public:
+  philosopher(int id_i,
+              boost::mutex& left_i,
+              boost::mutex& right_i);
+  void begin();
+
+private:
+  boost::thread action, hunger;
+
+  void busy(int loops=1);
+  void eat();
+  void think();
+
+  void loop();
+  void hungry();
+
+  int id;
+
+  double bellyfull;
+  bool full, starved;
+
+  boost::mutex &left, &right;
+  state s;
+};