Concepts of programming languages Lecture 9 Wouter Swierstra Faculty of Science Information and Computing Sciences 1
Last time ▶ How do other (typed) languages support this style of metaprogramming ? ▶ Case studies : when do people use refmection? ▶ Embedding DSLs using quasiquotation . Faculty of Science Information and Computing Sciences 2
This time Concurrency and parallelism ▶ Why is this important? ▶ What are these two concepts? ▶ How does Erlang address these challenges? Faculty of Science Information and Computing Sciences 3
Modern server software is demanding to develop and operate: It must be available at all times and in all locations; it must reply within milliseconds to user requests; it must respond quickly to capacity demands; it must process a lot of data and even more traffjc; it must adapt quickly to changing product needs; and, in many cases, it must accommodate a large engineering organization, its many engineers the proverbial cooks in a big, messy kitchen. Marius Eriksen, Twitter Principle Engineer, Functional at Scale , CACM December 2016 Faculty of Science Information and Computing Sciences 4
Concurrency & parallelism A parallel program is a program that uses multiplicity of computer hardware to perform a computation more quickly A concurrent program has multiple threads of control . Conceptually, these threads execute ‘at the same’ time, interleaving their efgects. These notions are not the same! Programs may be both parallel and concurrent, one of the two, or neither. Faculty of Science Information and Computing Sciences 5
Determinism and non-determinism A program that will return a single result is said to be deterministic . When difgerent runs of the program may yield difgerent results, the program is non-deterministic . Concurrent programs are necessarily non-deterministic – depending on how threads are interleaved, they may compute difgerent results. Concurrent and non-deterministic programs are much harder to test and verify. Faculty of Science Information and Computing Sciences 6
Why care about concurrency and parallelism? Computers are not getting much faster: instead they have more and more cores. To exploit this hardware we need parallelism . Programs no longer run in isolation. They are inter-connected – to difgerent machines, to users, to subsystems. To structure such interconnected programs, we need concurrency . Faculty of Science Information and Computing Sciences 7
Why concurrency? First, scale implies concurrency. For example, a search engine may split its index into many small pieces (or shards) so the entire corpus can fjt in main memory. To satisfy queries effjciently, all shards must be queried concurrently. Second, communication between servers is asynchronous and must be handled concurrently for effjciency and safety. Marius Eriksen, Twitter Principle Engineer, Functional at Scale , CACM December 2016 Faculty of Science Information and Computing Sciences 8
Concurrency models Traditionally, concurrency is done through spawning or forking new threads. There are numerous synchronization primitives to co-ordinate between threads: locks, mutexes, semaphores, … If you’ve taken the course on Concurrency, you will have seen how to write algorithms using them. Faculty of Science Information and Computing Sciences 9
Concurrency models Programming with concurrency is really hard. In particular, once you have state that is mutable and shared between threads, it becomes almost impossible to reason about your program. How can both threads reach the critical section simultaneously? Faculty of Science Information and Computing Sciences 10
a=0; a = a + 1; if (a == 1) { critical_section(); } a = a + 1; if (a == 1) { critical_section(); } Thread one Thread two Faculty of Science Information and Computing Sciences 11
Atomicity Assignments are not atomic operations. Instead they read in the current value of a , increment that value, and store it again. This can cause all kinds of undesirable interaction! Check out The Deadlock Empire (https://deadlockempire.github.io/) or our Concurrency course. Programming with locks and threads directly is really hard . Faculty of Science Information and Computing Sciences 12
— Faculty of Science Information and Computing Sciences 13
Beyond locks and threads Locks and threads are at the heart of any concurrent program. More recently, languages have started to ofger difgerent abstractions , often built on top of simple locks and threads: ▶ actor model/message passing ▶ software transactional memory ▶ exploiting data parallelism ▶ executing code on GPUs These all represent difgerent tools, specifjcally designed for difgerent problems. Faculty of Science Information and Computing Sciences 14
Erlang Originally developed in 1986 at Ericsson, it aimed to improve the software running on telephony switches. Specifjcally designed for concurrent programming with many difgerent processes that might fail at any time. Open source release together with OTP (Open Telecom Platform) containing: ▶ Erlang compiler and interpreter; ▶ communication protocol between servers; ▶ a static analysis tool (Dialyzer); ▶ a distributed database server (Mnesia); ▶ … Faculty of Science Information and Computing Sciences 15
Social media: WhatsApp Grindr Betting websites William Hill Bet365 Telecoms TMobile AT&T Much, much more.. Does anyone use Erlang? Faculty of Science Information and Computing Sciences 16
Does anyone use Erlang? ▶ Social media: ▶ WhatsApp ▶ Grindr ▶ Betting websites ▶ William Hill ▶ Bet365 ▶ Telecoms ▶ TMobile ▶ AT&T ▶ Much, much more.. Faculty of Science Information and Computing Sciences 16
Erlang for Haskell programmers Erlang is: ▶ dynamically typed; ▶ strict rather than lazy; ▶ impure (there are no restrictions on efgects and assignments); ▶ the syntax is familiar, but slightly difgerent. Faculty of Science Information and Computing Sciences 17
qsort([]) -> []; qsort([X|XS]) -> qsort([Y || Y <- Xs, Y < X]) ++ [X] ++ qsort([Y || Y <- Xs, Y >= X]). Quicksort ▶ No ‘equations’ but ‘arrows’ when pattern matching. ▶ Clauses are separated with semi-colons; a function defjnition is fjnished with a period. ▶ All Erlang variables start with capital letters; names starting with lower-case letters are atoms . Faculty of Science Information and Computing Sciences 18
-module (myModuleName) - compile(export_all) qsort([]) -> ... Modules To compile the code, we need to include some module information This declares the module myModuleName and exports all its declarations. Faculty of Science Information and Computing Sciences 19
-module (hello). -export ([start / 0]). start() -> io:format("Hello Erlang!"). Hello Erlang! The export statement can be used to expose certain functions: note that each statements records the functions arity (the number of arguments it expects), but not its type . We can call the format function from the module io using io:format . Faculty of Science Information and Computing Sciences 20
Concurrency Concurrent Erlang programs are organized into processes, a lightweight virtual machine that can communicate with other processes. There are three important functions to defjne concurrent programs: ▶ spawn creates a new process; ▶ send sends a message to another process; ▶ receive receives a message sent by another process. Faculty of Science Information and Computing Sciences 21
Case study: a concurrent fjle server As a simple example to illustrate this concurrency model, consider defjning a simple concurrent fjle server and its client: ▶ the afile_server module waits for messages from the client; ▶ the afile_client module may send messages to the server requesting data. Faculty of Science Information and Computing Sciences 22
-module (afile_server) -export ([start / 1,loop / 1]) start(Dir) -> spawn(afile_server, loop, [Dir]) loop(Dir) -> ... Case study: the server Modules and processes are a bit like classes and objects: there may be many processes running code defjned in the same module. When a new afile_server is started using start , a new process is spawned. In this example, the process is spawned by calling the method loop from the module afile_server with the argument [Dir] . Faculty of Science Information and Computing Sciences 23
loop(Dir) -> receive {Client, list_dir} -> Client ! {self(), file:list_dir(Dir)}; {Client, {get_file, File}} -> Full = filename:join(Dir,File) Client ! {self(), file:read_file(Full)} end , loop(Dir). Case study: the server This code waits for a message from the client ( receive …). Once the message has been received and processed, it calls loop(Dir) again to receive a new message, ad infjnitum. Faculty of Science Information and Computing Sciences 24
receive {Client, list_dir} -> Client ! {self(), file:list_dir(Dir)}; {Client, {get_file, File}} -> Full = filename:join(Dir,File) Client ! {self(), file:read_file(Full)} end , Case study: the server The receive ... end statement pattern matches on the message it receives from the client. Note: variables bound are written with capitals; constants start with a lower-case letter. Faculty of Science Information and Computing Sciences 25
Recommend
More recommend