Anda di halaman 1dari 9

Parallel Programming Concepts

OpenHPI Course
Week 5 : Distributed Memory Parallelism
Unit 5.5: Programming with Actors
Dr. Peter Trger + Teaching Team

Actor Model
48

Carl Hewitt, Peter Bishop and Richard Steiger. A Universal Modular


Actor Formalism for Artificial Intelligence IJCAI 1973.
Mathematical model for concurrent computation
Actor as computational primitive
Local decisions, concurrently sends / receives messages
Has a mailbox for incoming messages
Concurrently creates more actors
Asynchronous one-way message sending
Changing topology allowed, typically no order guarantees
Recipient is identified by mailing address
Actors can send their own identity to other actors
Available as programming language extension or library
in many environments
OpenHPI | Parallel Programming Concepts | Dr. Peter Trger

Erlang Ericsson Language


49

Functional language with actor support


Designed for large-scale concurrency
First version in 1986 by Joe Armstrong, Ericsson Labs
Available as open source since 1998
Language goals driven by Ericsson product development
Scalable distributed execution of phone call handling software
with large number of concurrent activities
Fault-tolerant operation under timing constraints
Online software update
Users
Amazon EC2 SimpleDB , Delicious, Facebook chat, T-Mobile
SMS and authentication, Motorola call processing, Ericsson
GPRS and 3G mobile network products, CouchDB, EJabberD,
OpenHPI | Parallel Programming Concepts | Dr. Peter Trger

Concurrency in Erlang
50

Concurrency Oriented Programming


Actor processes are completely independent (shared nothing)
Synchronization and data exchange with message passing
Each actor process has an unforgeable name
If you know the name, you can send a message
Default approach is fire-and-forget
You can monitor remote actor processes
Using this gives you
Opportunity for massive parallelism
No additional penalty for distribution, despite latency issues
Easier fault tolerance capabilities
Concurrency by default
OpenHPI | Parallel Programming Concepts | Dr. Peter Trger

Actors in Erlang
51

Communication via message passing is part of the language


Send never fails, works asynchronously (PID ! Message)
Actors have mailbox functionality
Queue of received messages, selective fetching
Only messages from same source arrive in-order
receive statement with set of clauses, pattern matching
Process is suspended in receive operation until a match
receive
Pattern1 when Guard1 -> expr1, expr2, ..., expr_n;
Pattern2 when Guard2 -> expr1, expr2, ..., expr_n;
Other
-> expr1, expr2, ..., expr_n
end

OpenHPI | Parallel Programming Concepts | Dr. Peter Trger

Erlang Example: Ping Pong Actors


52

-module(tut15).
-export([test/0, ping/2, pong/0]).

Functions exported + #args

ping(0, Pong_PID) ->


Pong_PID ! finished,
io:format("Ping finished~n", []);

[erlang.org]

ping(N, Pong_PID) ->


Pong_PID ! {ping, self()},
receive
pong ->
io:format("Ping received pong~n", [])
end,
ping(N - 1, Pong_PID).
pong() ->
receive
finished ->
io:format("Pong finished~n", []);
{ping, Ping_PID} ->
io:format("Pong received ping~n", []),
Ping_PID ! pong,
pong()
end.
test() ->
Pong_PID = spawn(tut15, pong, []),
spawn(tut15, ping, [3, Pong_PID]).

Ping actor,
sending message to Pong
Blocking recursive receive,
scanning the mailbox

Pong actor
Blocking recursive receive,
scanning the mailbox

Sending message to Ping

Start Ping and Pong actors

Actors in Scala
53

Actor-based concurrency in Scala, similar to Erlang


Concurrency abstraction on top of threads or processes
Communication by non-blocking send operation and blocking
receive operation with matching functionality
actor {
var sum = 0
loop {
receive {
case Data(bytes)
=> sum += hash(bytes)
case GetSum(requester) => requester ! sum
}}}
All constructs are library functions (actor, loop, receiver, !)
Alternative self.receiveWithin() call with timeout
Case classes act as message type representation
OpenHPI | Parallel Programming Concepts | Dr. Peter Trger

Scala Example: Counter Actor


54

import scala.actors.Actor
import scala.actors.Actor._
case class Inc(amount: Int)
case class Value
class Counter extends Actor {
var counter: Int = 0;
def act() = {
while (true) {
receive {
case Inc(amount) =>
counter += amount
case Value =>
println("Value is "+counter)
exit()
}}}}
object ActorTest extends Application {
val counter = new Counter
counter.start()
for (i <- 0 until 100000) {
counter ! Inc(1)
}
counter ! Value
// Output: Value is 100000
}
OpenHPI | Parallel Programming Concepts | Dr. Peter Trger

Case classes,
acting as message types
Implementation of
the counter actor
Blocking receive loop,
scanning the mailbox

Start the counter actor


Send an Inc message
to the counter actor
Send a Value message
to the counter actor

Actor Deadlocks
Synchronous send operator !? available in Scala
Sends a message and blocks in receive afterwards
Intended for request-response pattern
// actorA
actorB !? Msg1(value) match {
case Response1(r) =>
//
}
receive {
case Msg2(value) =>
reply(Response2(value))
}

// actorB
actorA !? Msg2(value) match {
case Response2(r) =>
//
}
receive {
case Msg1(value) =>
reply(Response1(value))
}

Original asynchronous send makes deadlocks less probable


// actorA
actorB ! Msg1(value)
while (true) {
receive {
case Msg2(value) =>
reply(Response2(value))
case Response1(r) =>
// ...
}}

// actorB
actorA ! Msg2(value)
while (true) {
receive {
case Msg1(value) =>
reply(Response1(value))
case Response2(r) =>
// ...
}}

[http://savanne.be/articles/concurrency-in-erlang-scala/]

55

Anda mungkin juga menyukai