Lecture 34: Thread Pools & Futures; Intro to Consensus

COSC 273: Parallel and Distributed Computing

Spring 2023

Annoucements

  1. Leaderboard Submissions Tonight
  2. Take-home Quiz Wednesday-Friday on Sorting Networks

Executor Services

From Java API an ExecutorService is

[a]n Executor that provides methods to manage termination and methods that can produce a Future for tracking progress of one or more asynchronous tasks.

What Can ExecutorServices Do?

  • submit tasks
    • a task is Callable<T> or Runnable instance
    • a Future<T> is returned
  • invoke a Collection of tasks
    • a List of Future<T>s is returned

Callable<T> is an interface

  • implement call() method
  • call() returns a T

What is a Future?

Represents the result of a submitted task:

  • waits until task is complete before giving return value
  • stores return value when task is complete

Example.

ExecuterService pool = Executors.newFixedThreadPool(...);
Future<String> result = pool.submit(someTask);
System.out.println("result: " + result.get());

Activity

  1. Download lec34-futures.zip and run the program
  2. Understand what happens and why
  3. Modify the program so that:
    • completed tasks print in order submitted
    • printing can before all tasks complete

Consensus

Motivation I: Mission Critical Components

Suppose you’re designing an airplane

  1. Need computers to control everything
    • sensors for speed, thrust, flap positions, pitch, roll, yaw
    • must adjust constantly to fly
  2. But computers occasionally (regularly) crash/need restart

How to design around this issue?

Fault-Tolerance through Duplication?

Have multiple duplicate, independent systems

  • systems run in parallel
  • highly unlikely both crash simultaneously
    • restarts are infrequent
    • restarting one system won’t affect other system

The end of our worries?

Trouble Ahead

Suppose all systems working normally, but

  • system 1 says increase thrust
  • system 2 says decrease thrust
  • system 3 not responding (restart?)

What do we do?

Motivation II: Electronic Currency

Context. Decentralized electronic currency

  • money represented as digital tokens
    • tokens have unique IDs
  • unlike physical coins, digital tokens are easily duplicated

Question. If money can be duplicated, how can it hold value? How can one “spend” their money?

  • holding (storing) a token is not ownership
  • ownership is determined by history of transactions
  • transactions stored as a (distributed) ledger
    • i.e., blockchain

Problem: Double-Spending

Issue. Customer spends same digital token twice

  • Customer submits transaction giving coin $A$ to vendor $V$
  • Customer submits another transaction giving coin $A$ to vendor $W$

Question. How does the network decide which (if any) transaction is valid?

The Problem of Consensus

Have multiple processes with different views/inputs

  • For us, binary inputs
    • 0 = decrease thrust; accept transaction 0
    • 1 = increase thrust; accept transaction 1

Goal:

  • all processes agree on same output

More Formally

Setup:

  • $n$ processes/threads, $P_1, P_2, \ldots, P_n$
  • processes have unique IDs, $1, 2, \ldots, n$ (like ThreadId.get())
  • each process $i$ holds input $x_i = 0$ or $1$

Output:

  • each process $i$ outputs $b_i = 0$ or $1$

Failure:

  • Some process(es) may crash
    • failing process may perform some steps before failing
    • cannot distinguish slow from crash

Conditions for Consensus

  • Agreement: all processes output the same value

  • Validity: if all systems have the same input, they all output that value

  • Termination: all (non-faulty) processes decide on an output and terminate after a finite number of steps

Exercise

Devise an algorithm for consensus assuming:

  1. Extremely fair scheduler: all processes take a step before anyone takes a next step
    • execution in synchronous rounds
  2. No faulty processes
  3. Access to shared array of size $n$

Consensus with Faults

Suppose some process(es) may crash at any time during an execution…

  • Other processes can’t tell that a process crashes
    • e.g., cannot distinguish slow process from crashed

Not Consensus 1

How can we achieve…

  • Agreement: all processes output the same value
  • Validity: if all systems have the same input, they all output that value
  • Termination: all (non-faulty) processes decide on an output and terminate after a finite number of steps

Not Consensus 2

How can we achieve…

  • Agreement: all processes output the same value
  • Validity: if all systems have the same input, they all output that value
  • Termination: all (non-faulty) processes decide on an output and terminate after a finite number of steps

Not Consensus 3

How can we achieve…

  • Agreement: all processes output the same value
  • Validity: if all systems have the same input, they all output that value
  • Termination: all (non-faulty) processes decide on an output and terminate after a finite number of steps

So

Without too much trouble, we can achieve…

  • …consensus with synchronous rounds, no faults
  • …“consensus” without agreement
  • …“consensus” without validity
  • …“consensus” without termination

What about consensus with faults?

A Remarkable Fact

Theorem (FLP, 1985). There is no algorithm that achieves consensus in the presence of even a single faulty process.

  • Proven by Fischer, Lynch, and Paterson in 1985
    • their version of result for “message passing” model
    • ours is for shared memory with atomic read/writes
  • Surprise to the parallel/distributed computing community
  • Among most influential results in CS

Our Plan

Prove version of FLP result:

  • There is no wait-free protocol for consensus with read/write registers for any $n > 1$
    • wait-free is stronger assumption than termination

Next Time.

  • Specify computational model
  • Make preliminary observations
  • Outline argument