Systèmes Distribués Eddy Caron Introduction to Erlang Eddy Caron 2013 M1. ENS-Lyon 1.

45
Systèmes Distribués Eddy Caron Introduction to Erlang Introduction to Erlang Eddy Caron 2013 M1. ENS-Lyon 1

Transcript of Systèmes Distribués Eddy Caron Introduction to Erlang Eddy Caron 2013 M1. ENS-Lyon 1.

Page 1: Systèmes Distribués Eddy Caron Introduction to Erlang Eddy Caron 2013 M1. ENS-Lyon 1.

Systèmes Distribués Eddy Caron Introduction to Erlang

Introduction to Erlang

Eddy Caron

2013M1. ENS-Lyon

1

Page 2: Systèmes Distribués Eddy Caron Introduction to Erlang Eddy Caron 2013 M1. ENS-Lyon 1.

Systèmes Distribués Eddy Caron Introduction to Erlang

Piece of History

1982 – 1985 Experiments with programming of telecom using > 20 different languages. Conclusion: The language must be a very high level symbolic language in order to achive productivity gains ! (Leaves us with: Lisp , Prolog , Parlog ...)

1985 – 86 Experiments with Lisp, Prolog, Parlog etc. Conclusion: The language must contain primitives for concurrency and error recovery, and the execution model must not have back-tracking. (Rules out Lisp and Prolog). We must therefore develop our own language with the desirable features of Lisp, Prolog and Parlog, but with concurrency and error recovery built into the language.

1987 The first experiments with Erlang.

1993 Distribution is added to Erlang, which makes it possible to run a homgeneous Erlang system on a heterogeneous hardware. Decision to sell implementations Erlang externally. Separate organization in Ericsson started to maintain and support Erlang implementations and Erlang Tools.

2

Page 3: Systèmes Distribués Eddy Caron Introduction to Erlang Eddy Caron 2013 M1. ENS-Lyon 1.

Systèmes Distribués Eddy Caron Introduction to Erlang

The Erlang Shell

The Erlang Shell

You can use Ctrl+c to break

3

[ecaron@aspen bin]$ ./erlErlang R15B02 (erts-5.9.2) [source] [smp:8:8] [async-threads:0] [hipe] [kernel-poll:false]

Eshell V5.9.2 (abort with ^G)1> 2+5.72> (42+6)*33/4.396.03> halt().[ecaron@aspen bin]$

[ecaron@aspen bin]$ ./erlErlang R15B02 (erts-5.9.2) [source] [smp:8:8] [async-threads:0] [hipe] [kernel-poll:false]

Eshell V5.9.2 (abort with ^G)1> 2+5.72> (42+6)*33/4.396.03> halt().[ecaron@aspen bin]$

BREAK: (a)bort (c)ontinue (p)roc info (i)nfo (l)oaded (v)ersion (k)ill (D)b-tables (d)istribution

BREAK: (a)bort (c)ontinue (p)roc info (i)nfo (l)oaded (v)ersion (k)ill (D)b-tables (d)istribution

Page 4: Systèmes Distribués Eddy Caron Introduction to Erlang Eddy Caron 2013 M1. ENS-Lyon 1.

Systèmes Distribués Eddy Caron Introduction to Erlang

Hello world

‘%’ starts a comment

‘.’ ends a declaration

Every function must be in a moduleone module per source file

source file name is module name + “.erl”

‘:’ used for calling functions in other modules

4

Page 5: Systèmes Distribués Eddy Caron Introduction to Erlang Eddy Caron 2013 M1. ENS-Lyon 1.

Systèmes Distribués Eddy Caron Introduction to Erlang

Module and Functions

A programming language isn't much use if you can just run code from the shell.

use it

5

[ecaron@aspen Erlang]$ cat mult2.erl -module(mult2).-export([double/1]).

double(X) -> 2 * X.

[ecaron@aspen Erlang]$ cat mult2.erl -module(mult2).-export([double/1]).

double(X) -> 2 * X.

[ecaron@aspen Erlang]$ erlErlang R15B02 (erts-5.9.2) [source] [smp:8:8] [async-threads:0] [hipe] [kernel-poll:false]

Eshell V5.9.2 (abort with ^G)1> c(mult2).{ok,mult2}2> mult2:double(6). 12

[ecaron@aspen Erlang]$ erlErlang R15B02 (erts-5.9.2) [source] [smp:8:8] [async-threads:0] [hipe] [kernel-poll:false]

Eshell V5.9.2 (abort with ^G)1> c(mult2).{ok,mult2}2> mult2:double(6). 12

Compilation is ok !Compilation is ok !

Page 6: Systèmes Distribués Eddy Caron Introduction to Erlang Eddy Caron 2013 M1. ENS-Lyon 1.

Systèmes Distribués Eddy Caron Introduction to Erlang

Numbers

Regular numbers

#-notation for base-N integers

$-notation for character codes (ISO-8859-1)

6

123-3456712.345 -27.45e-05

123-3456712.345 -27.45e-05

1> 16#ff.255

1> 16#ff.255

2> $A.65

2> $A.65

Page 7: Systèmes Distribués Eddy Caron Introduction to Erlang Eddy Caron 2013 M1. ENS-Lyon 1.

Systèmes Distribués Eddy Caron Introduction to Erlang

Atoms

<!!>Must start with lower case character or be quoted

Similar to hashed stringsuse only one word of data

constant-time equality test

7

fridayunquoted_atoms_cannot_contain_blanks’A quoted atom with several blanks’’hello \n my friend’

fridayunquoted_atoms_cannot_contain_blanks’A quoted atom with several blanks’’hello \n my friend’

Page 8: Systèmes Distribués Eddy Caron Introduction to Erlang Eddy Caron 2013 M1. ENS-Lyon 1.

Systèmes Distribués Eddy Caron Introduction to Erlang

Tuples

Terms seprated by ‘,’ and enclosed in {}

A fixed number of items (similar to structure or record in conventional programming languages)

A tuple whose first element is an atom is called a tagged tuple

8

{123, bcd}{123, def, abc}{person, 'Jax', ’Teller'}{abc, {def, 123}, jkl}{}

{123, bcd}{123, def, abc}{person, 'Jax', ’Teller'}{abc, {def, 123}, jkl}{}

Page 9: Systèmes Distribués Eddy Caron Introduction to Erlang Eddy Caron 2013 M1. ENS-Lyon 1.

Systèmes Distribués Eddy Caron Introduction to Erlang

Other Data Types

Functions

Binaries

Process identifiers

References: A reference is a term which is unique in an Erlang runtime system, created by calling make_ref/0.

Erlang values in general are called « terms »

All terms are ordered and can be compared with ‘<’, ‘>’, ‘==’, ‘=:=’ , etc. 9

Module:fun(Arg1,Arg2,… Argn)Module:fun(Arg1,Arg2,… Argn)

Bin = <<Bin0,...>>Bin = <<Bin0,...>>

1> spawn(m, f, []).<0.51.0>1> spawn(m, f, []).<0.51.0>

Page 10: Systèmes Distribués Eddy Caron Introduction to Erlang Eddy Caron 2013 M1. ENS-Lyon 1.

Systèmes Distribués Eddy Caron Introduction to Erlang

Recursive Functions

Variables start with upper-case characters

‘;’ separates function clauses

‘,’ separates instructions

Variables are local to the function clause

Pattern matching and guards to select clauses

10

Page 11: Systèmes Distribués Eddy Caron Introduction to Erlang Eddy Caron 2013 M1. ENS-Lyon 1.

Systèmes Distribués Eddy Caron Introduction to Erlang

Compile and run

recurs.erlrecurs.erl

Recursive Functions

11

-module(recurs).-export([fac/1]). fac(0) -> 1; fac(N) -> N * fac(N-1).

-module(recurs).-export([fac/1]). fac(0) -> 1; fac(N) -> N * fac(N-1).

[ecaron@aspen Erlang]$ erlErlang R15B02 (erts-5.9.2) [source] [smp:8:8] [async-threads:0] [hipe] [kernel-poll:false]

Eshell V5.9.2 (abort with ^G)1> c(recurs).{ok,recurs}2> recurs:fac(6).720

[ecaron@aspen Erlang]$ erlErlang R15B02 (erts-5.9.2) [source] [smp:8:8] [async-threads:0] [hipe] [kernel-poll:false]

Eshell V5.9.2 (abort with ^G)1> c(recurs).{ok,recurs}2> recurs:fac(6).720

Page 12: Systèmes Distribués Eddy Caron Introduction to Erlang Eddy Caron 2013 M1. ENS-Lyon 1.

Systèmes Distribués Eddy Caron Introduction to Erlang

dblfunc.erldblfunc.erl

Recursive Functions

Compile and run

12

-module(dblfunc).-export([fac/1, mult/2]).

fac(1) -> 1;fac(N) -> N * fac(N - 1).

mult(X, Y) -> X * Y.

-module(dblfunc).-export([fac/1, mult/2]).

fac(1) -> 1;fac(N) -> N * fac(N - 1).

mult(X, Y) -> X * Y.

[ecaron@aspen Erlang]$ erlErlang R15B02 (erts-5.9.2) [source] [smp:8:8] [async-threads:0] [hipe] [kernel-poll:false]

Eshell V5.9.2 (abort with ^G)1> c(dblfunc).{ok,dblfunc}2> dblfunc:fac(4).243> dblfunc:mult(dblfunc:fac(4),2).48

[ecaron@aspen Erlang]$ erlErlang R15B02 (erts-5.9.2) [source] [smp:8:8] [async-threads:0] [hipe] [kernel-poll:false]

Eshell V5.9.2 (abort with ^G)1> c(dblfunc).{ok,dblfunc}2> dblfunc:fac(4).243> dblfunc:mult(dblfunc:fac(4),2).48

Page 13: Systèmes Distribués Eddy Caron Introduction to Erlang Eddy Caron 2013 M1. ENS-Lyon 1.

Systèmes Distribués Eddy Caron Introduction to Erlang

The arity is part of the function name

Non-exported functions are local to the modulemylists.erlmylists.erl

Tail Recursion

13

-module(mylists).-export([reverse/1]).reverse(L) -> reverse(L, []).reverse([H|T], L) -> reverse(T, [H|L]);reverse([], L) -> L.

-module(mylists).-export([reverse/1]).reverse(L) -> reverse(L, []).reverse([H|T], L) -> reverse(T, [H|L]);reverse([], L) -> L.

> mylists:reverse([3,2,1]).[1,2,3]> mylists:reverse([3,2,1]).[1,2,3]

Page 14: Systèmes Distribués Eddy Caron Introduction to Erlang Eddy Caron 2013 M1. ENS-Lyon 1.

Systèmes Distribués Eddy Caron Introduction to Erlang

Tail Recursion

14

> mylists:reverse([1,2,3]).[3,2,1]> mylists:reverse([1,2,3]).[3,2,1]

reverse([1,2,3])->reverse([1,2,3],[]).->reverse([2,3],[1])->reverse([3],[2,1])->reverse([],[3,2,1])->[3,2,1]

mylists.erlmylists.erl

-module(mylists).-export([reverse/1]).reverse(L) -> reverse(L, []).reverse([H|T], L) -> reverse(T, [H|L]);reverse([], L) -> L.

-module(mylists).-export([reverse/1]).reverse(L) -> reverse(L, []).reverse([H|T], L) -> reverse(T, [H|L]);reverse([], L) -> L.

Page 15: Systèmes Distribués Eddy Caron Introduction to Erlang Eddy Caron 2013 M1. ENS-Lyon 1.

Systèmes Distribués Eddy Caron Introduction to Erlang

Recursion over Lists

Pattern-matching selects components of the data

<!!!> ‘_’ is a “don’t care” pattern (not a variable)

‘[]’ is the empty list

‘[X,Y,Z]’ is a list with exactly three elements

‘[X,Y,Z|Tail]’ has three or more elements

15

Page 16: Systèmes Distribués Eddy Caron Introduction to Erlang Eddy Caron 2013 M1. ENS-Lyon 1.

Systèmes Distribués Eddy Caron Introduction to Erlang

List Recursion with Accumulator

The same syntax is used to construct lists

Strings are simply lists of character codes

Avoid adding data to the end of the list

16

Page 17: Systèmes Distribués Eddy Caron Introduction to Erlang Eddy Caron 2013 M1. ENS-Lyon 1.

Systèmes Distribués Eddy Caron Introduction to Erlang

Built-in Functions

Implemented in C

All the type tests and conversions are BIFs

Most BIFs (not all) are in the module “erlang”

Many common BIFs are auto-imported (recognized without writing “erlang:...”)

Operators (‘+’,’-’,’*’,’/’,...) are also really BIFs

Described in the BIFS manual

17

Page 18: Systèmes Distribués Eddy Caron Introduction to Erlang Eddy Caron 2013 M1. ENS-Lyon 1.

Systèmes Distribués Eddy Caron Introduction to Erlang

Built-in Functions

Some examples

18

1> date().{2012,10,23}2> time().{1,14,35}3> length([1,2,3,4,5]).54> size({a,b,c}).35> atom_to_list(an_atom)."an_atom"6> list_to_tuple([1,2,3,4]).{1,2,3,4}7> integer_to_list(3412)."3412"8> tuple_to_list({}).[]

1> date().{2012,10,23}2> time().{1,14,35}3> length([1,2,3,4,5]).54> size({a,b,c}).35> atom_to_list(an_atom)."an_atom"6> list_to_tuple([1,2,3,4]).{1,2,3,4}7> integer_to_list(3412)."3412"8> tuple_to_list({}).[]

Page 19: Systèmes Distribués Eddy Caron Introduction to Erlang Eddy Caron 2013 M1. ENS-Lyon 1.

Systèmes Distribués Eddy Caron Introduction to Erlang

Application LibrariesKernel

a. erlang

b. code

c. file

d. inet

e. os

Stdliba. lists

b. dict

c. sets

d. ...

19

Standard Libraries

Page 20: Systèmes Distribués Eddy Caron Introduction to Erlang Eddy Caron 2013 M1. ENS-Lyon 1.

Systèmes Distribués Eddy Caron Introduction to Erlang

Expressions

Boolean and/or/xor are strict (always evaluate both arguments)

Use andalso/orelse for short circuit evaluation

‘==’ for equality, not ‘=’

Always use parentheses when not absolutely certain about the precedence

20

Page 21: Systèmes Distribués Eddy Caron Introduction to Erlang Eddy Caron 2013 M1. ENS-Lyon 1.

Systèmes Distribués Eddy Caron Introduction to Erlang

Fun Expressions

21

1> Fun1 = fun (X) -> X+1 end.#Fun<erl_eval.6.39074546>2> Fun1(2).33> Fun2 = fun (X) when X>=5 -> gt; (X) -> lt end.#Fun<erl_eval.6.39074546>4> Fun2(7).gt

1> Fun1 = fun (X) -> X+1 end.#Fun<erl_eval.6.39074546>2> Fun1(2).33> Fun2 = fun (X) when X>=5 -> gt; (X) -> lt end.#Fun<erl_eval.6.39074546>4> Fun2(7).gt

Page 22: Systèmes Distribués Eddy Caron Introduction to Erlang Eddy Caron 2013 M1. ENS-Lyon 1.

Systèmes Distribués Eddy Caron Introduction to Erlang

Pattern Matching

Match failure causes run-time error

Successful matching binds the variablesbut only if they are not already bound to a value

previously bound variables can be used in a pattern

a new variable can also be repeated in a pattern

22

-module(pm).-export([mylength/1]).mylength([]) -> 0;mylength([_|T]) -> mylength(T) + 1.

-module(pm).-export([mylength/1]).mylength([]) -> 0;mylength([_|T]) -> mylength(T) + 1.

Page 23: Systèmes Distribués Eddy Caron Introduction to Erlang Eddy Caron 2013 M1. ENS-Lyon 1.

Systèmes Distribués Eddy Caron Introduction to Erlang

Case-switches

Any number of clauses

Patterns and guards, just as in functions

‘;’ separates clauses

Use ‘_’ as catch-all

Variables may also begin with underscore signals “I don’t intend to use this value”

23

is_valid_signal(Signal) -> case Signal of {signal, _What, _From, _To} -> true; {signal, _What, _To} -> true; _Else -> false end.

is_valid_signal(Signal) -> case Signal of {signal, _What, _From, _To} -> true; {signal, _What, _To} -> true; _Else -> false end.

Page 24: Systèmes Distribués Eddy Caron Introduction to Erlang Eddy Caron 2013 M1. ENS-Lyon 1.

Systèmes Distribués Eddy Caron Introduction to Erlang

If-switches

Like a case-switch without the patterns and the ‘when’ keyword

Use ‘true’ as catch-all

24

factorial(N) when N == 0 -> 1;

factorial(N) when N > 0 -> N * factorial(N - 1).

factorial(N) when N == 0 -> 1;

factorial(N) when N > 0 -> N * factorial(N - 1).

Page 25: Systèmes Distribués Eddy Caron Introduction to Erlang Eddy Caron 2013 M1. ENS-Lyon 1.

Systèmes Distribués Eddy Caron Introduction to Erlang

Pattern Matching

When

If

Case

25

Switching

factorial(0) -> 1; factorial(N) -> N * factorial(N-1).

factorial(0) -> 1; factorial(N) -> N * factorial(N-1).

factorial(N) when N == 0 -> 1; factorial(N) when N > 0 ->

N * factorial(N - 1).

factorial(N) when N == 0 -> 1; factorial(N) when N > 0 ->

N * factorial(N - 1).

factorial(N) -> ifN == 0 -> 1; N > 0 -> N * factorial(N - 1) end.

factorial(N) -> ifN == 0 -> 1; N > 0 -> N * factorial(N - 1) end.

factorial(N) -> 1 case (N) of

0 -> 1; N when N > 0 -> N * factorial(N - 1) end.

factorial(N) -> 1 case (N) of

0 -> 1; N when N > 0 -> N * factorial(N - 1) end.

Page 26: Systèmes Distribués Eddy Caron Introduction to Erlang Eddy Caron 2013 M1. ENS-Lyon 1.

Systèmes Distribués Eddy Caron Introduction to Erlang

List Processing BIFs List Processing Functions

Tuple Processing BIFS

26

List and Tuple Processing

atom_to_list(A)float_to_list(F)integer_to_list(I)tuple_to_list(T)list_to_atom(L)...hd(L)tl(L)length(L)

atom_to_list(A)float_to_list(F)integer_to_list(I)tuple_to_list(T)list_to_atom(L)...hd(L)tl(L)length(L)

member(X,L)append(L1,L2)reverse(L)delete_all(X,L)

member(X,L)append(L1,L2)reverse(L)delete_all(X,L)

tuple_to_list(T)element(N,T)setelement(N,T,Val)size(L)…

tuple_to_list(T)element(N,T)setelement(N,T,Val)size(L)…

Page 27: Systèmes Distribués Eddy Caron Introduction to Erlang Eddy Caron 2013 M1. ENS-Lyon 1.

Systèmes Distribués Eddy Caron Introduction to Erlang

Catching Exceptions

throw: user defined

error: runtime errors

exit: end process

only catch throw exceptionsnormally

27

-module(catch_it).-compile(export_all). % An example of throw and catch g(X) when X >= 13 -> ok;g(X) when X < 13 -> throw({exception1, bad_number}). % Throw in g/1 % Catch in start/1 start(Input) -> case catch g(Input) of {exception1, Why} -> io:format("trouble is ~w ", [ Why ]); NormalReturnValue -> io:format("good input ~w ", [ NormalReturnValue ] ) end.

-module(catch_it).-compile(export_all). % An example of throw and catch g(X) when X >= 13 -> ok;g(X) when X < 13 -> throw({exception1, bad_number}). % Throw in g/1 % Catch in start/1 start(Input) -> case catch g(Input) of {exception1, Why} -> io:format("trouble is ~w ", [ Why ]); NormalReturnValue -> io:format("good input ~w ", [ NormalReturnValue ] ) end.

8> c(catch_it). {ok,catch_it} 9> catch_it:start(12).trouble is bad_number ok 10> catch_it:start(13).good input ok ok

8> c(catch_it). {ok,catch_it} 9> catch_it:start(12).trouble is bad_number ok 10> catch_it:start(13).good input ok ok

Page 28: Systèmes Distribués Eddy Caron Introduction to Erlang Eddy Caron 2013 M1. ENS-Lyon 1.

Systèmes Distribués Eddy Caron Introduction to Erlang

Processes

Code is executed by a process

A process keeps track of the program pointer, the stack, the variables values, etc.

Every process has a unique process identifier: PIDProcesses are concurrent

Virtual machine layer processes

Preemptive multitasking

Little overhead (e.g. 100.000 processes)

Can use multiple CPUs on multiprocessor machines 28

Page 29: Systèmes Distribués Eddy Caron Introduction to Erlang Eddy Caron 2013 M1. ENS-Lyon 1.

Systèmes Distribués Eddy Caron Introduction to Erlang

Concurrency

• Several processes may use the same program code at the same time

– each has own program counter, stack, and variables – programmer need not think about other processes

updating the variables

29

Page 30: Systèmes Distribués Eddy Caron Introduction to Erlang Eddy Caron 2013 M1. ENS-Lyon 1.

Systèmes Distribués Eddy Caron Introduction to Erlang

Message Passing

• “!” is the send operator– Pid of the receiver is used as the address

• Messages are sent asynchronously – The sender continues immediately

• Any value can be sent as a message

30

1> c(echo).{ok,echo}2> Id=echo:start(), 2> Id ! {self(),hello}.> echo: <0.38.0> Msg: hello {<0.31.0>,hello}

1> c(echo).{ok,echo}2> Id=echo:start(), 2> Id ! {self(),hello}.> echo: <0.38.0> Msg: hello {<0.31.0>,hello}

echo.erlecho.erl

-module(echo).-export([start/0,loop/0]).start() -> spawn(echo, loop, []).loop() -> receive {From, Message} -> io:format("> echo: ~w Msg: ~w ~n", [self(), Message]), From ! Message, loop()end.

-module(echo).-export([start/0,loop/0]).start() -> spawn(echo, loop, []).loop() -> receive {From, Message} -> io:format("> echo: ~w Msg: ~w ~n", [self(), Message]), From ! Message, loop()end.

Page 31: Systèmes Distribués Eddy Caron Introduction to Erlang Eddy Caron 2013 M1. ENS-Lyon 1.

Systèmes Distribués Eddy Caron Introduction to Erlang

Message Queues

• Each process has a message queue (mailbox)– incoming messages are placed in the queue (no size

limit)

• A process receives a message when it extracts it from the mailbox

– need not take the first message in the queue

31

Page 32: Systèmes Distribués Eddy Caron Introduction to Erlang Eddy Caron 2013 M1. ENS-Lyon 1.

Systèmes Distribués Eddy Caron Introduction to Erlang

Receive a Message

• receive-expressions are similar to case switches – patterns are used to match messages in the mailbox – messages in the queue are tested in order– only one message can be extracted each time

• Selective receive– Patterns and guards permit message

selection – receive-clauses are tried in order – If no message matches, the process

suspends and waits for a new message

32

Page 33: Systèmes Distribués Eddy Caron Introduction to Erlang Eddy Caron 2013 M1. ENS-Lyon 1.

Systèmes Distribués Eddy Caron Introduction to Erlang

Receive with Timeout

• A receive-expression can have an after-part– can be an integer (milliseconds) or “infinity”

• The process waits until a matching message arrives, or the timeout limit is exceeded

– soft real-time: no guarantees

33

sleep(T)- process suspends for T ms.sleep(T) ->

receive after T -> true end.

suspend() - process suspends indefinitely.suspend() ->

receiveafter infinity -> trueend.

sleep(T)- process suspends for T ms.sleep(T) ->

receive after T -> true end.

suspend() - process suspends indefinitely.suspend() ->

receiveafter infinity -> trueend.

Page 34: Systèmes Distribués Eddy Caron Introduction to Erlang Eddy Caron 2013 M1. ENS-Lyon 1.

Systèmes Distribués Eddy Caron Introduction to Erlang

Send and Reply

• Pids are often included in messages (self()), so that the receiver can reply to the sender

– If the reply includes the Pid of the second process, it is easier for the first process to recognize the reply

• Message order– The only guaranteed message order is

when both the sender and the receiver are the same for both messages (first-in, first- out)

• Selecting Unordered Messages– Using selective receive, it is possible to choose which messages to accept,

even if they arrive in a different order

34

Page 35: Systèmes Distribués Eddy Caron Introduction to Erlang Eddy Caron 2013 M1. ENS-Lyon 1.

Systèmes Distribués Eddy Caron Introduction to Erlang

Starting Processes

• The “spawn” function creates a new process • The new process will run the specified function

– The spawn operation always returns immediately

• The return value is the Pid of the “child”

35

Page 36: Systèmes Distribués Eddy Caron Introduction to Erlang Eddy Caron 2013 M1. ENS-Lyon 1.

Systèmes Distribués Eddy Caron Introduction to Erlang

Ping Pong

36

tut16.erltut16.erl

-module(tut16).-export([start/0, ping/1, pong/0]).ping(0) -> pong ! finished, io:format("ping finished~n", []);ping(N) -> pong ! {ping, self()}, receive pong -> io:format("Ping received pong~n", []) end, ping(N - 1).pong() -> receive finished -> io:format("Pong finished~n", []); {ping, Ping_PID} -> io:format("Pong received ping~n", []), Ping_PID ! pong, pong() end.start() -> register(pong, spawn(tut16, pong, [])), spawn(tut16, ping, [3]).

-module(tut16).-export([start/0, ping/1, pong/0]).ping(0) -> pong ! finished, io:format("ping finished~n", []);ping(N) -> pong ! {ping, self()}, receive pong -> io:format("Ping received pong~n", []) end, ping(N - 1).pong() -> receive finished -> io:format("Pong finished~n", []); {ping, Ping_PID} -> io:format("Pong received ping~n", []), Ping_PID ! pong, pong() end.start() -> register(pong, spawn(tut16, pong, [])), spawn(tut16, ping, [3]).

1> c(tut16).{ok,tut16}2> tut16:start().Pong received ping<0.39.0>Ping received pongPong received pingPing received pongPong received pingPing received pongping finishedPong finished

1> c(tut16).{ok,tut16}2> tut16:start().Pong received ping<0.39.0>Ping received pongPong received pingPing received pongPong received pingPing received pongping finishedPong finished

Page 37: Systèmes Distribués Eddy Caron Introduction to Erlang Eddy Caron 2013 M1. ENS-Lyon 1.

Systèmes Distribués Eddy Caron Introduction to Erlang

Process Termination

• Process Termination A process terminates when:– it finishes the function call that it started with

a. There is an exception that is not caught

• All messages sent to a terminated process will be thrown away

• Same Pid will not be used before long time

37

Page 38: Systèmes Distribués Eddy Caron Introduction to Erlang Eddy Caron 2013 M1. ENS-Lyon 1.

Systèmes Distribués Eddy Caron Introduction to Erlang

Registered Processes

• A process can be registered under a name • Any process can send a message to a registered process,

or look up the Pid • The Pid might change (if the process is restarted and re-

registered), but the name stays the same

38

Pid = spawn(?MODULE, server, []),register(myserver, Pid),myserver ! Msg.

Pid = spawn(?MODULE, server, []),register(myserver, Pid),myserver ! Msg.

Page 39: Systèmes Distribués Eddy Caron Introduction to Erlang Eddy Caron 2013 M1. ENS-Lyon 1.

Systèmes Distribués Eddy Caron Introduction to Erlang

Links and Exit Signals

• Any two processes can be linked– Links are always bidirectionnal

• When a process dies, an exit signal is sent to all linked processes, which are also killed

– normal exit does not kill other processe

• If a process sets its trap_exit flag, all signals will be caught and turned into normal messages

– process_flag(trap_exit, true) – Signal is turned into message {‘EXIT’, Pid, ErrorTerm}

• This way, a process can watch other processes 39

Page 40: Systèmes Distribués Eddy Caron Introduction to Erlang Eddy Caron 2013 M1. ENS-Lyon 1.

Systèmes Distribués Eddy Caron Introduction to Erlang

Distribution

• Running “erl” with the flag “-name xxx”– starts the Erlang network distribution system– Makes the virtual machine emulator a “node” (‘[email protected]’)

• Erlang nodes can communicate over the network (but must find each other first)

• Possible to send a Pid from one node to another (Pids are unique across nodes)

• You can send a message to any process through its Pid (even on another node)

• You can run several Erlang nodes (with different names) on the same computer

40

Page 41: Systèmes Distribués Eddy Caron Introduction to Erlang Eddy Caron 2013 M1. ENS-Lyon 1.

Systèmes Distribués Eddy Caron Introduction to Erlang

Connecting Nodes

• Nodes are connected the first time they try to communicate

• The function “net_adm:ping(Node)” is the easiest way to set up a connection between nodes

– returns “pong” or “pang”

• Send a message to a registered process using – “{Name,Node} ! Message”

41

Page 42: Systèmes Distribués Eddy Caron Introduction to Erlang Eddy Caron 2013 M1. ENS-Lyon 1.

Systèmes Distribués Eddy Caron Introduction to Erlang

Running Remote Processes

• Variants of the spawn function can start processes directly on another node

• The module ‘global’ contains functions for – registering and using named processes over the whole

network of connected nodes

• setting global locks

42

Page 43: Systèmes Distribués Eddy Caron Introduction to Erlang Eddy Caron 2013 M1. ENS-Lyon 1.

Systèmes Distribués Eddy Caron Introduction to Erlang

Ports:Talking to the Outside

• Talks to an external (or linked-in) C program • A port is connected to the process that opened it • The port sends data to the process in messages • A process can send data to the port

43

Page 44: Systèmes Distribués Eddy Caron Introduction to Erlang Eddy Caron 2013 M1. ENS-Lyon 1.

Systèmes Distribués Eddy Caron Introduction to Erlang

Conclusion

• Try Erlang in practical session…• … and send me your own conclusion

44

Page 45: Systèmes Distribués Eddy Caron Introduction to Erlang Eddy Caron 2013 M1. ENS-Lyon 1.

Systèmes Distribués Eddy Caron Introduction to Erlang

References

• Special and greatful thanks to Franck Petit et Sebastien Tixeuil• http://www.erlang.org• http://en.wikibooks.org/wiki/Erlang_Programming

• Use case pour normalien ;-)– Un Caml Light Distribué [Elkamel Merah , Allaoua Chaoui]– « … Pour l’extension concurrente de Caml Light nous proposons quelques

primitives avec une semantique tres simple en utilisant le modele du langage de programmation ERLANG. Le support de la creation dynamique de processus et de la communication asynchrone entre processus sont les deux principales extensions du langage Caml Light. "

45