Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
A
Actor Framework
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Metrics
Environments
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
cpp-libs
Actor Framework
Commits
828669b0
Commit
828669b0
authored
Jan 24, 2012
by
neverlord
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
dining philosophers
parent
03b3b68b
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
259 additions
and
1 deletion
+259
-1
.gitignore
.gitignore
+1
-0
cppa/either.hpp
cppa/either.hpp
+0
-0
examples/Makefile.am
examples/Makefile.am
+4
-1
examples/dining_philosophers.cpp
examples/dining_philosophers.cpp
+254
-0
No files found.
.gitignore
View file @
828669b0
...
...
@@ -60,3 +60,4 @@ examples/announce_example_4
examples/announce_example_5
examples/hello_world_example
examples/math_actor_example
examples/dining_philosophers
cppa/
util/
either.hpp
→
cppa/either.hpp
View file @
828669b0
File moved
examples/Makefile.am
View file @
828669b0
...
...
@@ -9,7 +9,8 @@ noinst_PROGRAMS = announce_example_1 \
announce_example_4
\
announce_example_5
\
hello_world_example
\
math_actor_example
math_actor_example
\
dining_philosophers
announce_example_1_SOURCES
=
announce_example_1.cpp
announce_example_2_SOURCES
=
announce_example_2.cpp
...
...
@@ -18,6 +19,7 @@ announce_example_4_SOURCES = announce_example_4.cpp
announce_example_5_SOURCES
=
announce_example_5.cpp
hello_world_example_SOURCES
=
hello_world_example.cpp
math_actor_example_SOURCES
=
math_actor_example.cpp
dining_philosophers_SOURCES
=
dining_philosophers.cpp
EXAMPLES_LIBS
=
-L
../.libs/
-lcppa
$(BOOST_LDFLAGS)
$(BOOST_THREAD_LIB)
...
...
@@ -28,4 +30,5 @@ announce_example_4_LDADD = $(EXAMPLES_LIBS)
announce_example_5_LDADD
=
$(EXAMPLES_LIBS)
hello_world_example_LDADD
=
$(EXAMPLES_LIBS)
math_actor_example_LDADD
=
$(EXAMPLES_LIBS)
dining_philosophers_LDADD
=
$(EXAMPLES_LIBS)
examples/dining_philosophers.cpp
0 → 100644
View file @
828669b0
/******************************************************************************\
* ___ __ *
* /\_ \ __/\ \ *
* \//\ \ /\_\ \ \____ ___ _____ _____ __ *
* \ \ \ \/\ \ \ '__`\ /'___\/\ '__`\/\ '__`\ /'__`\ *
* \_\ \_\ \ \ \ \L\ \/\ \__/\ \ \L\ \ \ \L\ \/\ \L\.\_ *
* /\____\\ \_\ \_,__/\ \____\\ \ ,__/\ \ ,__/\ \__/.\_\ *
* \/____/ \/_/\/___/ \/____/ \ \ \/ \ \ \/ \/__/\/_/ *
* \ \_\ \ \_\ *
* \/_/ \/_/ *
* *
* Copyright (C) 2011, 2012 *
* Dominik Charousset <dominik.charousset@haw-hamburg.de> *
* *
* This file is part of libcppa. *
* libcppa is free software: you can redistribute it and/or modify it under *
* the terms of the GNU Lesser General Public License as published by the *
* Free Software Foundation, either version 3 of the License *
* or (at your option) any later version. *
* *
* libcppa is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *
* See the GNU Lesser General Public License for more details. *
* *
* You should have received a copy of the GNU Lesser General Public License *
* along with libcppa. If not, see <http://www.gnu.org/licenses/>. *
\******************************************************************************/
#include <vector>
#include <chrono>
#include <iostream>
#include <sstream>
#include "cppa/cppa.hpp"
#include "cppa/fsm_actor.hpp"
using
std
::
cout
;
using
std
::
endl
;
using
std
::
chrono
::
seconds
;
using
namespace
cppa
;
// either taken by a philosopher or available
struct
chopstick
:
fsm_actor
<
chopstick
>
{
behavior
&
init_state
;
behavior
available
;
behavior
taken_by
(
actor_ptr
const
&
philos
)
{
return
(
on
<
atom
(
"take"
),
actor_ptr
>
()
>>
[
=
](
actor_ptr
other
)
{
send
(
other
,
atom
(
"busy"
),
this
);
},
on
(
atom
(
"put"
),
philos
)
>>
[
=
]()
{
become
(
&
available
);
}
);
}
chopstick
()
:
init_state
(
available
)
{
available
=
(
on
<
atom
(
"take"
),
actor_ptr
>
()
>>
[
=
](
actor_ptr
philos
)
{
send
(
philos
,
atom
(
"taken"
),
this
);
become
(
taken_by
(
philos
));
}
);
}
};
/* See: http://www.dalnefre.com/wp/2010/08/dining-philosophers-in-humus/
*
*
* +-------------+ {(busy|taken), Y}
* /-------->| thinking |<------------------\
* | +-------------+ |
* | | |
* | | {eat} |
* | | |
* | V |
* | +-------------+ {busy, X} +-------------+
* | | hungry |----------->| denied |
* | +-------------+ +-------------+
* | |
* | | {taken, X}
* | |
* | V
* | +-------------+
* | | wait_for(Y) |
* | +-------------+
* | | |
* | {busy, Y} | | {taken, Y}
* \-----------/ |
* | V
* | {think} +-------------+
* \---------| eating |
* +-------------+
*
*
* [ X = left => Y = right ]
* [ X = right => Y = left ]
*/
struct
philosopher
:
fsm_actor
<
philosopher
>
{
std
::
string
name
;
// the name of this philosopher
actor_ptr
left
;
// left chopstick
actor_ptr
right
;
// right chopstick
// note: we have to define all behaviors in the constructor because
// non-static member initialization are not (yet) implemented in GCC
behavior
thinking
;
behavior
hungry
;
behavior
denied
;
behavior
eating
;
behavior
init_state
;
// wait for second chopstick
behavior
waiting_for
(
actor_ptr
const
&
what
)
{
return
(
on
(
atom
(
"taken"
),
what
)
>>
[
=
]()
{
std
::
ostringstream
oss
;
oss
<<
name
<<
" has picked up chopsticks with IDs "
<<
left
->
id
()
<<
" and "
<<
right
->
id
()
<<
" and starts to eat
\n
"
;
cout
<<
oss
.
str
();
// eat some time
future_send
(
this
,
seconds
(
5
),
atom
(
"think"
));
become
(
&
eating
);
},
on
(
atom
(
"busy"
),
what
)
>>
[
=
]()
{
send
((
what
==
left
)
?
right
:
left
,
atom
(
"put"
),
this
);
send
(
this
,
atom
(
"eat"
));
become
(
&
thinking
);
}
);
}
philosopher
(
std
::
string
const
&
n
,
actor_ptr
const
&
l
,
actor_ptr
const
&
r
)
:
name
(
n
),
left
(
l
),
right
(
r
)
{
// a philosopher that receives {eat} stops thinking and becomes hungry
thinking
=
(
on
(
atom
(
"eat"
))
>>
[
=
]()
{
become
(
&
hungry
);
send
(
left
,
atom
(
"take"
),
this
);
send
(
right
,
atom
(
"take"
),
this
);
}
);
// wait for the first answer of a chopstick
hungry
=
(
on
(
atom
(
"taken"
),
left
)
>>
[
=
]()
{
become
(
waiting_for
(
right
));
},
on
(
atom
(
"taken"
),
right
)
>>
[
=
]()
{
become
(
waiting_for
(
left
));
},
on
<
atom
(
"busy"
),
actor_ptr
>
()
>>
[
=
]()
{
become
(
&
denied
);
}
);
// philosopher was not able to obtain the first chopstick
denied
=
(
on
<
atom
(
"taken"
),
actor_ptr
>
()
>>
[
=
](
actor_ptr
&
ptr
)
{
send
(
ptr
,
atom
(
"put"
),
this
);
send
(
this
,
atom
(
"eat"
));
become
(
&
thinking
);
},
on
<
atom
(
"busy"
),
actor_ptr
>
()
>>
[
=
]()
{
send
(
this
,
atom
(
"eat"
));
become
(
&
thinking
);
}
);
// philosopher obtained both chopsticsk and eats (for five seconds)
eating
=
(
on
(
atom
(
"think"
))
>>
[
=
]()
{
send
(
left
,
atom
(
"put"
),
this
);
send
(
right
,
atom
(
"put"
),
this
);
future_send
(
this
,
seconds
(
5
),
atom
(
"eat"
));
cout
<<
(
name
+
" puts down his chopsticks and starts to think
\n
"
);
become
(
&
thinking
);
}
);
// philosophers start to think after receiving {think}
init_state
=
(
on
(
atom
(
"think"
))
>>
[
=
]()
{
cout
<<
(
name
+
" starts to think
\n
"
);
future_send
(
this
,
seconds
(
5
),
atom
(
"eat"
));
become
(
&
thinking
);
}
);
}
};
int
main
()
{
// create five chopsticks
cout
<<
"chopstick ids:"
;
std
::
vector
<
actor_ptr
>
chopsticks
;
for
(
size_t
i
=
0
;
i
<
5
;
++
i
)
{
chopsticks
.
push_back
(
spawn
(
new
chopstick
));
cout
<<
" "
<<
chopsticks
.
back
()
->
id
();
}
cout
<<
endl
;
// a group to address all philosophers
auto
dinner_club
=
group
::
anonymous
();
// spawn five philosopher, each joining the Dinner Club
std
::
vector
<
std
::
string
>
names
=
{
"Plato"
,
"Hume"
,
"Kant"
,
"Nietzsche"
,
"Descartes"
};
for
(
size_t
i
=
0
;
i
<
5
;
++
i
)
{
spawn
(
new
philosopher
(
names
[
i
],
chopsticks
[
i
],
chopsticks
[(
i
+
1
)
%
5
])
)
->
join
(
dinner_club
);
}
// tell philosophers to start thinking
send
(
dinner_club
,
atom
(
"think"
));
// real philosophers are never done
await_all_others_done
();
return
0
;
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment