Post by Szabolcs FerencziPost by SPX2ok it seems i just made a first approach to dining philosophers
problem(i mean my first approach,
im aware many people from many places came up with much better
solutions)http://perlhobby.googlecode.com/svn/trunk/scripturi_perl_teste/thread...
You did not start with a simple problem, I must say.
My first remark is that your first solution has some logical flaw.
Namely, the problem says that the life of a philosopher alternates
between thinking and eating.
Philosopher n: (eat think)+
Your solution do not implement this but someting like thinking and
then attempting to eat and only eventually eat.
Philosopher n: (think+ eat)+
Next remark is that you demonstrate the typical mistake I have called
and make decision on the instant status of it. Remember, the `once
false, always false' only applies to sequential programs but not to
multi-threaded ones.
Third remark: Your `are_forks_free' query should use locking as well.
But that is not enough because the existence of this query should be
elminated or it should be moved inside another operation, e.g.
`grab_forks'. Anyway it is always a better idea to abstract the shared
resource and the associated operations on it into a package.
package Forks;
sub fork_op_1 {
<...>}
sub fork_op_n {
<...>}
;
Try not to implement any query interface for the packages of shared
variable handling whenever possible.
Also I would suggest you to make unit tests for your packages. Even
better if you can use test first development method for them.
Collecting the shared resource and the handling procedures into a
package is a way to compensate for the lack proper language means. In
a proper language there should be some keyword to mark which is a
shared resource and then the complier should check whether that shared
resource is properly accessed inside a critical region.
shared (s: integer);
...
with (s) do s := 1; end
Fourth remark: Try to test your code before publishing it. Your
current solution contains dead code. Note that if you just replace
your `while(1)' with `foreach(1..LIFETIME)', your program would
eventually terminate.
Technical remark: If you want to see your trace messages while your
threads are progressing, you can insert a `$|++;' statement after each
`print' statement. Even better if you extract the prints into a trace
block and you care about the mutual exclusion of the threads as well.
Do not forget that the screen or standard output is a shared resource
too.
package Trace;
my $screen : shared;
sub put_line { lock $screen; print shift, "\n"; $|++; }
;
Post by SPX2im thinking of also taking into consideration that the highest degree
of parallelisation in this
This problem is not about to demonstrate how you can exploit the
parallelism. It is rather a problem where some resource handling
issues arise such as deadlock and starvation. You should attempt to
give a solution where you can demonstrate that deadlock and starvation
do not apply.
Best Regards,
Szabolcs
thank you very much for the heads up.
i agree with you that i misunderstood the problem in the sense that i
was
doing something like:
----------
are forks available ?
yes: eat , meditate
no : meditate
----------
while i should have done it like this
----------
are forks available ?
yes: eat , meditate
no : wait for forks,eat ,meditate
----------
i have kept the other branch of the if that shows
if a philosopher did not aquire forks so that it shows me if
i found a good or bad solution.
ive read also the solution presented by tanenbaum and he
has this array of semaphores wich are the forks at the same time,so
he seems to have double semantism for an entry in such an array
1)it is 0 if fork is in use and 1 if its not
2)its a semaphore with blocking capabilities
unfortunately i do not have yet a good grasp of Perl OOP so that i can
implement what you say about packages,altough i believe its for the
best.
(i tried today and failed miserably because what im reading on perl
oop is
just some chapter in a book i found interesting,but its not focusing
particularly
on oop,its a more borader book http://greenteapress.com/perl/perl.pdf
, when
i finish it i hope ill get some good book on oop)
i got that the simplest solution is a semaphore on the critical region
http://perlhobby.googlecode.com/svn/trunk/scripturi_perl_teste/threads/diningphilosophers_semaph.pl
also ive followed your advice and made a solution using locks
http://perlhobby.googlecode.com/svn/trunk/scripturi_perl_teste/threads/diningphilosophers_lock.pl
and got a solution and interesting(to me) i got something else also
a "solution" where only philosopher 1 gets to eat and meditate.
http://perlhobby.googlecode.com/svn/trunk/scripturi_perl_teste/threads/diningphilosophers_stuck.pl
(this is the weirdest thing because on linux it gets stuck on
philosopher 1 and doesnt let go
while on windows it gets on moving with other threads as well,i cant
explain this difference of behaviour
and i think that the logical one should be the one on linux because it
has a lock in the while and
no other thread gets tu use @forks)
about the locking of the screen ... i havent figgured out a better way
than this
http://perlmonks.org/?node_id=619092
ive started up a discussion there...i didnt know how to do it very
well.
some other question i have is the "for(1..LIFETIME)" - i think this
will be system-dependant
in time metric i mean...or am i wrong ?