76
Programming Language Basics Companion slides for The Art of Multiprocessor Programming by Maurice Herlihy & Nir Shavit

Programming Language Basics Companion slides for The Art of Multiprocessor Programming by Maurice Herlihy & Nir Shavit

Embed Size (px)

Citation preview

Page 1: Programming Language Basics Companion slides for The Art of Multiprocessor Programming by Maurice Herlihy & Nir Shavit

Programming Language Basics

Companion slides forThe Art of Multiprocessor Programming

by Maurice Herlihy & Nir Shavit

Page 2: Programming Language Basics Companion slides for The Art of Multiprocessor Programming by Maurice Herlihy & Nir Shavit

Art of Multiprocessor Programming

2

Computer Science isn’t really About Programming

• Any more than– Astronomy is about telescopes– French Literature is about unfiltered

cigarettes

Page 3: Programming Language Basics Companion slides for The Art of Multiprocessor Programming by Maurice Herlihy & Nir Shavit

Art of Multiprocessor Programming

3

Nevertheless

• We need a programming language to state algorithms

• We use Java– High-level

• Sometimes a little too high level

– Most of you have seen it before• And may see it again

Page 4: Programming Language Basics Companion slides for The Art of Multiprocessor Programming by Maurice Herlihy & Nir Shavit

Art of Multiprocessor Programming

4

Other Languages

• PThreads– C and C++

• C#

• MPI

• Etc…

Page 5: Programming Language Basics Companion slides for The Art of Multiprocessor Programming by Maurice Herlihy & Nir Shavit

Art of Multiprocessor Programming

5

Threads

• Execution of a single sequential program• You can tell a thread

– What to do– When to start

• You can– Wait for it to finish

• Other stuff:– Interrupt it, give it priority, etc.

Page 6: Programming Language Basics Companion slides for The Art of Multiprocessor Programming by Maurice Herlihy & Nir Shavit

Art of Multiprocessor Programming

6

Threads in Java

• Class java.lang.Thread• Each thread has a method

– Void run()

• Executes when it starts

• Thread vanishes when it returns

• You must provide this method

Page 7: Programming Language Basics Companion slides for The Art of Multiprocessor Programming by Maurice Herlihy & Nir Shavit

Art of Multiprocessor Programming

7

Creating a Thread

• Create a Runnable object– Runnable is an interface– Provides run() method

• Pass Runnable object to thread constructor

Page 8: Programming Language Basics Companion slides for The Art of Multiprocessor Programming by Maurice Herlihy & Nir Shavit

Art of Multiprocessor Programming

8

A Runnable Classpublic class Hello implements Runnable { String message; public Hello(m) { message = m; } public void run() { System.out.println(message); }}

Page 9: Programming Language Basics Companion slides for The Art of Multiprocessor Programming by Maurice Herlihy & Nir Shavit

Art of Multiprocessor Programming

9

A Runnable Classpublic class Hello implements Runnable { String message; public Hello(m) { message = m; } public void run() { System.out.println(message); }}

Runnable interface

Page 10: Programming Language Basics Companion slides for The Art of Multiprocessor Programming by Maurice Herlihy & Nir Shavit

Art of Multiprocessor Programming

10

Creating a ThreadString m = “Hello from ” + i;Runnable h = new Hello(m);Thread t = new Thread(h);

Page 11: Programming Language Basics Companion slides for The Art of Multiprocessor Programming by Maurice Herlihy & Nir Shavit

Art of Multiprocessor Programming

11

Creating a ThreadString m = “Hello from ” + i;Runnable h = new Hello(m);Thread t = new Thread(h);

Create a Runnable object

Page 12: Programming Language Basics Companion slides for The Art of Multiprocessor Programming by Maurice Herlihy & Nir Shavit

Art of Multiprocessor Programming

12

Creating a ThreadString m = “Hello from ” + i;Runnable h = new Hello(m);Thread t = new Thread(h);

Create the thread

Page 13: Programming Language Basics Companion slides for The Art of Multiprocessor Programming by Maurice Herlihy & Nir Shavit

Art of Multiprocessor Programming

13

Syntactic Help

• Defining a single-use class like Hello can be a nuisance

• Java provides special syntax

• Anonymous inner classes– May be more trouble than it’s worth– You should recognize it

Page 14: Programming Language Basics Companion slides for The Art of Multiprocessor Programming by Maurice Herlihy & Nir Shavit

Art of Multiprocessor Programming

14

Anonymous Inner Classt = new Thread( new Runnable() { public void run() { System.out.println(m); } } );

Page 15: Programming Language Basics Companion slides for The Art of Multiprocessor Programming by Maurice Herlihy & Nir Shavit

Art of Multiprocessor Programming

15

Anonymous Inner Classt = new Thread( new Runnable() { public void run() { System.out.println(m); } } );

Creates object of anonymous Runnable

class

Page 16: Programming Language Basics Companion slides for The Art of Multiprocessor Programming by Maurice Herlihy & Nir Shavit

Art of Multiprocessor Programming

16

Anonymous Inner Classt = new Thread( new Runnable() { public void run() { System.out.println(m); } } );

Calls Thread constructor with anonymous object

Page 17: Programming Language Basics Companion slides for The Art of Multiprocessor Programming by Maurice Herlihy & Nir Shavit

Art of Multiprocessor Programming

17

Starting a Thread

• Starts the new thread

• Caller returns immediately

• Caller & thread run in parallel

t.start();

Page 18: Programming Language Basics Companion slides for The Art of Multiprocessor Programming by Maurice Herlihy & Nir Shavit

Art of Multiprocessor Programming

18

Joining a Thread

• Blocks the caller

• Waits for the thread to finish

• Returns when the thread is done

t.join();

Page 19: Programming Language Basics Companion slides for The Art of Multiprocessor Programming by Maurice Herlihy & Nir Shavit

Art of Multiprocessor Programming

19

Monitors

• Each object has an implicit lock

• Managed by synchronized modifer– Methods– Code blocks

• OK for easy cases

• Not always for hard cases

Page 20: Programming Language Basics Companion slides for The Art of Multiprocessor Programming by Maurice Herlihy & Nir Shavit

Art of Multiprocessor Programming

20

Call Center Scenario

• Calls arrive faster than they can be answered– Play recorded message

• “your call is very important to us …”

– Put call in queue• Play insipid music …

– Operators dequeue call when ready

Page 21: Programming Language Basics Companion slides for The Art of Multiprocessor Programming by Maurice Herlihy & Nir Shavit

Art of Multiprocessor Programming

21

Bad Queue Implementationclass Queue<T> { int head = 0, tail = 0; T[] items = new T[QSIZE]; public enq(T x) { items[(tail++) % QSIZE] = x; } public T deq() { return items[(head++) % QSIZE] }}

Page 22: Programming Language Basics Companion slides for The Art of Multiprocessor Programming by Maurice Herlihy & Nir Shavit

Art of Multiprocessor Programming

22

class Queue<T> { int head = 0, tail = 0; T[] items = new T[QSIZE]; public enq(T x) { items[(tail++) % QSIZE] = x; } public T deq() { return items[(head++) % QSIZE] }}

Bad Queue Implementation

Works for generic type T

Page 23: Programming Language Basics Companion slides for The Art of Multiprocessor Programming by Maurice Herlihy & Nir Shavit

Art of Multiprocessor Programming

23

class Queue<T> { int head = 0, tail = 0; T[] items = new T[QSIZE]; public enq(T x) { items[(tail++) % QSIZE] = x; } public T deq() { return items[(head++) % QSIZE] }}

Bad Queue Implementation

Array of T items

Page 24: Programming Language Basics Companion slides for The Art of Multiprocessor Programming by Maurice Herlihy & Nir Shavit

Art of Multiprocessor Programming

24

class Queue<T> { int head = 0, tail = 0; T[] items = new T[QSIZE]; public enq(T x) { items[(tail++) % QSIZE] = x; } public T deq() { return items[(head++) % QSIZE] }}

Bad Queue Implementation

next slot to dequeue, 1st empty slot

Page 25: Programming Language Basics Companion slides for The Art of Multiprocessor Programming by Maurice Herlihy & Nir Shavit

Art of Multiprocessor Programming

25

class Queue<T> { int head = 0, tail = 0; T[] items = new T[QSIZE]; public enq(T x) { items[(tail++) % QSIZE] = x; } public T deq() { return items[(head++) % QSIZE] }}

Bad Queue ImplementationPut in empty slot,

advance head

Page 26: Programming Language Basics Companion slides for The Art of Multiprocessor Programming by Maurice Herlihy & Nir Shavit

Art of Multiprocessor Programming

26

Of course, this doesn’t work

tail

Page 27: Programming Language Basics Companion slides for The Art of Multiprocessor Programming by Maurice Herlihy & Nir Shavit

Art of Multiprocessor Programming

27

Mutual Exclusion

• Only one thread modifying queue fields at a time

• Use synchronized methods– Locks object on call– Releases lock on return

Page 28: Programming Language Basics Companion slides for The Art of Multiprocessor Programming by Maurice Herlihy & Nir Shavit

Art of Multiprocessor Programming

28

Mutual Exclusion

tail

Page 29: Programming Language Basics Companion slides for The Art of Multiprocessor Programming by Maurice Herlihy & Nir Shavit

Art of Multiprocessor Programming

29

Synchronized Methodclass Queue<T> { … public synchronized enq(T x) { items[(tail++) % QSIZE]; } ...}

Page 30: Programming Language Basics Companion slides for The Art of Multiprocessor Programming by Maurice Herlihy & Nir Shavit

Art of Multiprocessor Programming

30

Synchronized Methodclass Queue<T> { … public synchronized enq(T x) { items[(tail++) % QSIZE]; } ...}

Lock acquired on entry, released on exit

Page 31: Programming Language Basics Companion slides for The Art of Multiprocessor Programming by Maurice Herlihy & Nir Shavit

Art of Multiprocessor Programming

31

Syntactic Sugarclass Queue<T> { … public enq(T x) { synchronized (this) { items[(tail++) % QSIZE]; } } ...}

Page 32: Programming Language Basics Companion slides for The Art of Multiprocessor Programming by Maurice Herlihy & Nir Shavit

Art of Multiprocessor Programming

32

Syntactic Sugarclass Queue<T> { … public enq(T x) { synchronized (this) { items[(tail++) % QSIZE]; } } ...}

Same meaning, more verbose

Page 33: Programming Language Basics Companion slides for The Art of Multiprocessor Programming by Maurice Herlihy & Nir Shavit

Art of Multiprocessor Programming

33

Vocabulary

• A synchronized method locks the object

• No other thread can call another synchronized method for that same object

• Code in middle is critical section

Page 34: Programming Language Basics Companion slides for The Art of Multiprocessor Programming by Maurice Herlihy & Nir Shavit

Art of Multiprocessor Programming

34

Re-entrant Locks

• What happens if you lock the same object twice?– In Java, no deadlock– Keeps track of number of times locked and

unlocked– Unlock occurs when they balance out

Page 35: Programming Language Basics Companion slides for The Art of Multiprocessor Programming by Maurice Herlihy & Nir Shavit

Art of Multiprocessor Programming

35

Still Doesn’t Workclass Queue<T> { … public synchronized enq(T x) { items[(tail++) % QSIZE] = x; } ...}

What if the array is full?

Page 36: Programming Language Basics Companion slides for The Art of Multiprocessor Programming by Maurice Herlihy & Nir Shavit

Art of Multiprocessor Programming

36

Waiting

• What if– Enqueuer finds a full array?– Dequeuer finds an empty array?

• Throw an exception?– What can caller do?– Repeated retries wasteful

• Wait for something to happen

Page 37: Programming Language Basics Companion slides for The Art of Multiprocessor Programming by Maurice Herlihy & Nir Shavit

Art of Multiprocessor Programming

37

Waiting Synchronized Methodclass Queue<T> { … public synchronized enq(T x) { while (tail - head == QSIZE) {}; items[(tail++) % QSIZE] = x; } ...}

Page 38: Programming Language Basics Companion slides for The Art of Multiprocessor Programming by Maurice Herlihy & Nir Shavit

Art of Multiprocessor Programming

38

class Queue<T> { … public synchronized enq(T x) { while (tail - head == QSIZE) {}; items[(tail++) % QSIZE] = x; } ...}

Waiting Synchronized Method

Spin while the array is full

Page 39: Programming Language Basics Companion slides for The Art of Multiprocessor Programming by Maurice Herlihy & Nir Shavit

Art of Multiprocessor Programming

39

Deadlock

• Enqueuer is– Waiting for a dequeuer– While holding the lock

• Dequeuer– Waiting for enqueuer to release lock

• Nothing will ever happen

Page 40: Programming Language Basics Companion slides for The Art of Multiprocessor Programming by Maurice Herlihy & Nir Shavit

Art of Multiprocessor Programming

40

Waiting Thread

• Release lock while waiting

• When “something happens”– Reacquire lock– Either

• Rerelease lock & resume waiting• Finish up and return

Page 41: Programming Language Basics Companion slides for The Art of Multiprocessor Programming by Maurice Herlihy & Nir Shavit

Art of Multiprocessor Programming

41

Styles of Waiting

• Spinning– Repeatedly retest condition

• Blocking– Ask OS to run someone else

Page 42: Programming Language Basics Companion slides for The Art of Multiprocessor Programming by Maurice Herlihy & Nir Shavit

Art of Multiprocessor Programming

42

Styles of Waiting

• Spinning– Good for very short intervals– Expensive to call OS – Works only on multiprocessors!

• Blocking– Good for longer intervals– Processor can do work

• Clever libraries sometimes mix

Page 43: Programming Language Basics Companion slides for The Art of Multiprocessor Programming by Maurice Herlihy & Nir Shavit

Art of Multiprocessor Programming

43

The wait() Method

• Releases lock on q

• Sleeps (gives up processor)

• Awakens (resumes running)

• Reacquires lock & returns

q.wait();

Page 44: Programming Language Basics Companion slides for The Art of Multiprocessor Programming by Maurice Herlihy & Nir Shavit

Art of Multiprocessor Programming

44

The wait() Methodclass Queue<T> { … public synchronized enq(T x) { while (tail – head == QSIZE) { wait(); }; items[(head++) % QSIZE] = x; } ...}

Page 45: Programming Language Basics Companion slides for The Art of Multiprocessor Programming by Maurice Herlihy & Nir Shavit

Art of Multiprocessor Programming

45

class Queue<T> { … public synchronized enq(T x) { while (tail – head == QSIZE) { wait(); }; items[(head++) % QSIZE] = x; } ...}

Waiting Synchronized Method

Keep retesting condition

Page 46: Programming Language Basics Companion slides for The Art of Multiprocessor Programming by Maurice Herlihy & Nir Shavit

Art of Multiprocessor Programming

46

class Queue<T> { … public synchronized enq(T x) { while (tail – head == QSIZE) { wait(); }; items[(head++) % QSIZE] = x; } ...}

Waiting Synchronized Method

Keep retesting condition

Release lock & sleep

Page 47: Programming Language Basics Companion slides for The Art of Multiprocessor Programming by Maurice Herlihy & Nir Shavit

Art of Multiprocessor Programming

47

class Queue<T> { … public synchronized enq(T x) { while (tail – head == QSIZE) { wait(); }; items[(head++) % QSIZE] = x; } ...}

Waiting Synchronized Method

Why while and not if?

Page 48: Programming Language Basics Companion slides for The Art of Multiprocessor Programming by Maurice Herlihy & Nir Shavit

Art of Multiprocessor Programming

48

Wake up and Smell the Coffee

• When does a waiting thread awaken?– Must be notified by another thread – when something has happened

• Failure to notify in a timely way is called a “lost wakeup”

Page 49: Programming Language Basics Companion slides for The Art of Multiprocessor Programming by Maurice Herlihy & Nir Shavit

Art of Multiprocessor Programming

49

The wait() Method

• Awakens one waiting thread

• Which will reacquire lock & returns

q.notify();

Page 50: Programming Language Basics Companion slides for The Art of Multiprocessor Programming by Maurice Herlihy & Nir Shavit

Art of Multiprocessor Programming

50

The wait() Method

• Awakens all waiting threads

• Which will reacquire lock & return

q.notifyAll();

Page 51: Programming Language Basics Companion slides for The Art of Multiprocessor Programming by Maurice Herlihy & Nir Shavit

Art of Multiprocessor Programming

51

The wait() Methodpublic synchronized enq(T x) { while (tail - head == QSIZE) { wait(); }; items[(head++) % QSIZE] = x; if (tail-head == 1) { notify(); }}

Page 52: Programming Language Basics Companion slides for The Art of Multiprocessor Programming by Maurice Herlihy & Nir Shavit

Art of Multiprocessor Programming

52

public synchronized enq(T x) { while (tail - head == QSIZE) { wait(); }; items[(head++) % QSIZE] = x; if (tail-head == 1) { notify(); }}

The wait() Method

Wait for empty slot

Page 53: Programming Language Basics Companion slides for The Art of Multiprocessor Programming by Maurice Herlihy & Nir Shavit

Art of Multiprocessor Programming

53

public synchronized enq(T x) { while (tail - head == QSIZE) { wait(); }; items[(head++) % QSIZE] = x; if (tail-head == 1) { notify(); }}

The wait() Method

Stuff item into array

Page 54: Programming Language Basics Companion slides for The Art of Multiprocessor Programming by Maurice Herlihy & Nir Shavit

Art of Multiprocessor Programming

54

public synchronized enq(T x) { while (tail - head == QSIZE) { wait(); }; items[(head++) % QSIZE] = x; if (tail-head == 1) { notify(); }}

The wait() Method

If the queue was empty, wake up a dequeuer

Page 55: Programming Language Basics Companion slides for The Art of Multiprocessor Programming by Maurice Herlihy & Nir Shavit

Art of Multiprocessor Programming

55

Lost Wakeup

• This code has a lost wakeup bug

• Possible to have– Waiting dequeuer– Non-empty queue

• Because not enough threads awakened

Page 56: Programming Language Basics Companion slides for The Art of Multiprocessor Programming by Maurice Herlihy & Nir Shavit

Art of Multiprocessor Programming

56

Empty queue, waiting dequeuers

Zzz …

Zzz …

Page 57: Programming Language Basics Companion slides for The Art of Multiprocessor Programming by Maurice Herlihy & Nir Shavit

Art of Multiprocessor Programming

57

Enqueuer puts item in queue

Zzz …Zzz …

Page 58: Programming Language Basics Companion slides for The Art of Multiprocessor Programming by Maurice Herlihy & Nir Shavit

Art of Multiprocessor Programming

58

Since queue was empty, wakes dequeuer

Zzz …

Ouch!notify()

this!

Page 59: Programming Language Basics Companion slides for The Art of Multiprocessor Programming by Maurice Herlihy & Nir Shavit

Art of Multiprocessor Programming

59

1st Dequeuer slow, overtaken by enqueuers

Zzz …Must have coffee …

Page 60: Programming Language Basics Companion slides for The Art of Multiprocessor Programming by Maurice Herlihy & Nir Shavit

Art of Multiprocessor Programming

60

1st Dequeuer finishes

Zzz …

Page 61: Programming Language Basics Companion slides for The Art of Multiprocessor Programming by Maurice Herlihy & Nir Shavit

Art of Multiprocessor Programming

61

Solutions

• Don’t write buggy code d’oh!

• Always call notifyAll()• Can also use timed waits

– Wake up after specified time

Page 62: Programming Language Basics Companion slides for The Art of Multiprocessor Programming by Maurice Herlihy & Nir Shavit

Art of Multiprocessor Programming

62

Thread-Local Data

• In many of our examples we assume– Threads have unique ids– In range 0,…,n-1

• Where do they come from?– Long-lived data– Unique to a thread

Page 63: Programming Language Basics Companion slides for The Art of Multiprocessor Programming by Maurice Herlihy & Nir Shavit

Art of Multiprocessor Programming

63

Thread-Local Data in Java

• ThreadLocal<T> class

• No built-in language support

• Library classes– Syntax is awkward– Very useful anyway

Page 64: Programming Language Basics Companion slides for The Art of Multiprocessor Programming by Maurice Herlihy & Nir Shavit

Art of Multiprocessor Programming

64

ThreadLocal methods

• Changes calling thread’s version of object

• Other threads’ versions unaffected

ThreadLocal<T> local;T x = …;local.set(x);

Page 65: Programming Language Basics Companion slides for The Art of Multiprocessor Programming by Maurice Herlihy & Nir Shavit

Art of Multiprocessor Programming

65

ThreadLocal methods

• Returns calling thread’s version of object

ThreadLocal<T> local;T x = local.get();

Page 66: Programming Language Basics Companion slides for The Art of Multiprocessor Programming by Maurice Herlihy & Nir Shavit

Art of Multiprocessor Programming

66

Initializing ThreadLocals

• Called by get() method the first time the thread-local variable is accessed.

T x = local.initialValue();

Page 67: Programming Language Basics Companion slides for The Art of Multiprocessor Programming by Maurice Herlihy & Nir Shavit

Art of Multiprocessor Programming

67

Example

• Return unique thread id

• Take a number first time called

int me = ThreadID.get()

Page 68: Programming Language Basics Companion slides for The Art of Multiprocessor Programming by Maurice Herlihy & Nir Shavit

Art of Multiprocessor Programming

68

Thread-Local IDspublic class ThreadID { static volatile int nextID = 0; private

static LocalID threadID = new LocalID(); public static int get() { return threadID.get(); } … // define LocalID here}

Page 69: Programming Language Basics Companion slides for The Art of Multiprocessor Programming by Maurice Herlihy & Nir Shavit

Art of Multiprocessor Programming

69

Thread-Local IDspublic class ThreadID { static volatile int nextID = 0; private

static LocalID threadID = new LocalID(); public static int get() { return threadID.get(); } … // define LocalID here}

Next ID to assign

Page 70: Programming Language Basics Companion slides for The Art of Multiprocessor Programming by Maurice Herlihy & Nir Shavit

Art of Multiprocessor Programming

70

Thread-Local IDspublic class ThreadID { static volatile int nextID = 0; private

static LocalID threadID = new LocalID(); public static int get() { return threadID.get(); } … // define LocalID here}

Declare & initialize thead-local ID

Page 71: Programming Language Basics Companion slides for The Art of Multiprocessor Programming by Maurice Herlihy & Nir Shavit

Art of Multiprocessor Programming

71

Thread-Local IDspublic class ThreadID { static volatile int nextID = 0; private

static LocalID threadID = new LocalID(); public static int get() { return threadID.get(); } … // define LocalID here}

Return value of thread-local ID

Page 72: Programming Language Basics Companion slides for The Art of Multiprocessor Programming by Maurice Herlihy & Nir Shavit

Art of Multiprocessor Programming

72

The Inner Classstatic class LocalID extends ThreadLocal<Integer> { synchronized Integer initialValue() { return nextID++; }}

Page 73: Programming Language Basics Companion slides for The Art of Multiprocessor Programming by Maurice Herlihy & Nir Shavit

Art of Multiprocessor Programming

73

The Inner Classstatic class LocalID extends ThreadLocal<Integer> { synchronized Integer initialValue() { return nextID++; }}

Subclass of ThreadLocal<Integer>

Page 74: Programming Language Basics Companion slides for The Art of Multiprocessor Programming by Maurice Herlihy & Nir Shavit

Art of Multiprocessor Programming

74

The Inner Classstatic class LocalID extends ThreadLocal<Integer> { synchronized Integer initialValue() { return nextID++; }}

Overrides initialValue()

Page 75: Programming Language Basics Companion slides for The Art of Multiprocessor Programming by Maurice Herlihy & Nir Shavit

Art of Multiprocessor Programming

75

Summary

• Threads– And how to control them

• Synchronized methods– Wait, notify, and NotifyAll

• Thread-Local objects

Page 76: Programming Language Basics Companion slides for The Art of Multiprocessor Programming by Maurice Herlihy & Nir Shavit

Art of Multiprocessor Programming

76

         This work is licensed under a Creative Commons Attribution-ShareAlike 2.5 License.

• You are free:– to Share — to copy, distribute and transmit the work – to Remix — to adapt the work

• Under the following conditions:– Attribution. You must attribute the work to “The Art of

Multiprocessor Programming” (but not in any way that suggests that the authors endorse you or your use of the work).

– Share Alike. If you alter, transform, or build upon this work, you may distribute the resulting work only under the same, similar or a compatible license.

• For any reuse or distribution, you must make clear to others the license terms of this work. The best way to do this is with a link to– http://creativecommons.org/licenses/by-sa/3.0/.

• Any of the above conditions can be waived if you get permission from the copyright holder.

• Nothing in this license impairs or restricts the author's moral rights.