Mercurial > hg > toys
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; +};