0% found this document useful (0 votes)
44 views

IA010: Principles of Programming Languages: 9. Concurrency

This document discusses concurrency and synchronization techniques. It begins by motivating the development of concurrent systems to increase speed on multi-processor hardware. It then covers levels of concurrency from machine instructions to whole programs. The document outlines topics including semaphores, monitors, concurrency in Java, message passing, and concurrency in functional languages. It provides examples of producer-consumer problems and mutual exclusion issues that concurrency aims to address.

Uploaded by

LUCKY SINGH
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
44 views

IA010: Principles of Programming Languages: 9. Concurrency

This document discusses concurrency and synchronization techniques. It begins by motivating the development of concurrent systems to increase speed on multi-processor hardware. It then covers levels of concurrency from machine instructions to whole programs. The document outlines topics including semaphores, monitors, concurrency in Java, message passing, and concurrency in functional languages. It provides examples of producer-consumer problems and mutual exclusion issues that concurrency aims to address.

Uploaded by

LUCKY SINGH
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 46

IA010: Principles of Programming

Languages

9. Concurrency

Jan Obdržálek [email protected]

Faculty of Informatics, Masaryk University, Brno

IA010 9. Concurrency 1
Motivation

Why develop concurrent systems?


1 to increase the speed of execution on multiple processors
(current architectures typically offer multiple cores/processors)
2 possible speed-up even on a single processor
(except for compute bound programs)
3 a different way of thinking about programs
(decomposition into tasks)
4 distributed applications
(multiple machines – connected locally or over the Internet)

Typical (today’s) applications:


• internet browser
• server

IA010 9. Concurrency 2
Concurrency

Levels of concurrency
• machine instructions
• statements (blocks of statements)
• subroutines (procedures, functions)
• whole programs

Goals
• scalability
(the speed increases with each added processor)
• portability
(reflects the speed of hardware development)

IA010 9. Concurrency 3
Outline

Concurrency: basic principles

Semaphores

Monitors

Concurrency in Java

Message passing

Concurrency in functional languages

IA010 9. Concurrency 4
Concurrency: basic principles

IA010 9. Concurrency 5
Multiprocessor architectures

• SIMD (Single-Instruction, Multiple-Data)


• each processor executes the same instruction, but on a
different part of the data
• typical instances: vector processors
• today e.g. in graphical cards (CUDA)
• MIMD (Multiple-Instruction, Multiple-Data)
• processor operate independently, but can synchronize
• distributed – each own data,
or shared memory
Today’s computers:
• more processors/cores on one chip
• the speed of one processor grows less dramatically than
some years ago

IA010 9. Concurrency 6
Categories of concurrency

• physical concurrency
• several program units literally “execute simultaneously”
• logical concurrency
• the execution is interleaved on a single processor
• but to the outside the environment looks as concurrent
• quasi-concurrency
• coroutines – not true concurrency

IA010 9. Concurrency 7
Basic concepts

• task
• a program unit, which can be executed independently of
other units
• sometimes called a process or a thread
• differences between tasks and subroutines:
1 a task can be executed implicitly
2 unit, which executes a task, may not necessarily wait for it
to finish
3 after a task is finished, the execution can continue from a
different point than the point of task execution
• heavyweight tasks
• each task has its own address space
• lightweight tasks
• all lightweight tasks share the same address space
• easier for the programmers
• can be more efficient (less overhead)
IA010 9. Concurrency 8
Basic concepts 2
task communication
• through shared variables
• message passing
• using parameters

synchronization
• a mechanism for controlling the task execution order
• cooperation synchronization
• one task waits for the other
• typical problem: producer-consumer
• competition synchronization
• several tasks compete for an access to a limited resource
• typical problem: mutual exclusion
• scheduler
• run-time system, which governs processor sharing among
tasks
IA010 9. Concurrency 9
Producers-consumers

• classical OS-theory problem


• two types of processes
• producers – create data
• consumers – use data
• data are passed using buffers of a limited capacity
• constraints
• if a consumer finds the buffer empty, he must wait for data
• if a producer finds the buffer full, he must wait for an empty
slot
• the processes must cooperate

IA010 9. Concurrency 10
Mutual exclusion
task A; task B;
x = x + 1; x = x * 2;
end A; end B;

• in the beginning: x=3


• problem: arithmetic operations on x are not atomic
1 fetch the value of x
2 execute the operation
3 store the value back in x

• after executing A and B: x=4 or x=6 or x=7

methods for providing mutually exclusive access


1 semaphores
2 monitors
3 message passing
IA010 9. Concurrency 11
Task life cycle

IA010 9. Concurrency [Sebesta] 12


Problems
liveness
• typically required
• if “something good” should happen, then it eventually
happens
• e.g. a scheduled task is given the processor in a finite
amount of time
• the computation proceeds towards a goal

deadlock
• if two or more tasks wait for each other
• example (tasks: A, B; resources: X, Y):
1 task A requests and obtains the resource X
2 task B requests and obtains the resource Y
3 task A requests the resource Y (requires X and Y)
4 task B requests the resource X (requires X and Y)
5 A and B mutually wain one for the other
IA010 9. Concurrency 13
Language designs for oncurrency

Shared Message Distributed


memory passing

Language Java, C# Ada

Extension OpenMP RPC


pthreads Internet
Library MPI
Win32 threads libraries

IA010 9. Concurrency 14
OpenMP example
#pragma omp for
for(int n=0; n<10; ++n) {
printf(" %d", n);
}
printf(".\n");

generated code
int this_thread = omp_get_thread_num();
int num_threads = omp_get_num_threads();
int my_start = (this_thread ) * 10 / num_threads;
int my_end = (this_thread+1) * 10 / num_threads;
for(int n=my_start; n<my_end; ++n)
printf(" %d", n);

possible outcome:
0 5 6 7 1 8 2 3 4 9.
IA010 9. Concurrency 15
Semaphores

IA010 9. Concurrency 16
Semaphores

• E. Dijkstra, 1965
• a simple mechanism
• based on the concept of guards
• condition + block of code
• allows the code to be executed only if the condition is
fulfilled
• semaphore is an implementation of guard
• semaphore data
• an integer counter + a queue of waiting tasks
• operations
• P (wait ) [probeer te verlagen – try to decrease]
• V (signal/resume ) [verhogen – increase]
• counter values
• 0, 1 – binary (mutex)
• 0 . . . n – counting semaphores

IA010 9. Concurrency 17
Semaphore implementation
wait(s)
if s.counter > 0 then
s.counter--
else
(s.queue).insert(P)
suspend P’s execution
end

signal(s)
if isempty(s.queue) then
s.counter++
else
P = (s.queue).remove()
mark P as ready
end
IA010 9. Concurrency 18
Semaphore example
both competion and cooperation

semaphore access, fullCount, emptyCount;


access.counter = 1;
fullCount.counter = 0;
emptyCount.counter = BUFLEN;

task producer; task consumer;


loop loop
-- produce VALUE --
wait(emptyCount); wait(fullCount);
wait(access); wait(access);
DEPOSIT(VALUE); FETCH(VALUE);
signal(access); signal(access);
signal(fullCount); signal(emptyCount);
-- consume VALUE --
end loop; end loop
end producer; end consumer;

IA010 9. Concurrency 19
Mutex in C – Linux 2.4.0
static int solo1_midi_release(struct inode *inode, struct file *file)
...
lock_kernel();
if (file->f_mode & FMODE_WRITE) {
add_wait_queue(&s->midi.owait, &wait);
for (;;) {
__set_current_state(TASK_INTERRUPTIBLE);
spin_lock_irqsave(&s->lock, flags);
count = s->midi.ocnt;
spin_unlock_irqrestore(&s->lock, flags);
if (count <= 0) break;
if (signal_pending(current)) break;
if (file->f_flags & O_NONBLOCK) {
remove_wait_queue(&s->midi.owait, &wait);
set_current_state(TASK_RUNNING);
return -EBUSY;
}
...
unlock_kernel();
return 0;
}
IA010 9. Concurrency 20
Semaphores: evaluation

pros
• simple and efficient
problems
• prone to errorneous use
(missing wait or signal)
• deadlocks

The semaphore is an elegant synchronization tool for an ideal


programmer who never makes mistakes.
P. B. Hansen, 1973

IA010 9. Concurrency 21
Monitors

IA010 9. Concurrency 22
Monitors

• solve some of the problems of semaphores


• formalized 1973 (Hansen), named 1974 (Hoare)
• use encapsulation
• shared data are packaged with operations on these data
• the representation is hidden – basically a kind of ADT
• access mechanism is part of the monitor
• if some subroutine of the monitor is running, all other
calling tasks are put into the queue
• guarantee mutual exclusion
• cooperation is programmer’s responsibility
• can be implementer using semaphores (and vice versa)
• e.g. synchronized in Java

IA010 9. Concurrency 23
Monitor example

[Sebesta]

IA010 9. Concurrency 24
Concurrency in Java

IA010 9. Concurrency 25
Java Threads
• threads are lightweight tasks
(i.e. sharing the same address space)
• communication using shared data
(and the join method)

Concurrent units
1 run() method of various objects
• descendants of the Thread class
• classes implementing Runnable
2 the main method
class MyThread extends Thread {
public void run() { ... }
}
...
Thread myTh = new MyThread();
myTh.start();

IA010 9. Concurrency 26
The thread class
selected methods

start executes the thread


yield voluntarily yields the processor
sleep postpones for a specified time (in ms)
(after which the thread joins the ready queue)
join waits for a (different) thread to finish
public void run() {
...
Thread myTh = new Thread();
myTh.start();
// do part of the computation of this thread
myTh.join(); // Wait for myTh to complete
// do the rest of the computation of this thread
}

interrupt notifies the thread that it should finish


IA010 9. Concurrency 27
Java scheduler

• threads can have different priorities


• threads with higher priorities are given a preference
• a lower priority thread can run only if there is not any ready
thread of a higher priority
• within the same priority the behaviour is implementation-
dependent (usually round-robin)

IA010 9. Concurrency 28
Java – mutual exclusion
1 semaphores
• java.util.concurrent.Semaphore
• counting semaphores
2 synchronized methods/blocks
• must be declared synchronized
• each object has its own implicit lock
and a ready task queue
• a synchronized method must first obtain the lock
• monitor = an object with all methods declared
synchronized
class Buffer {
private int [100] buf;
...
public synchronized void deposit(int item) { ... }
public synchronized int fetch() { ... }
...
}

IA010 9. Concurrency 29
Java – cooperation sync.

using the wait, notify, notifyAll methods


(inherited from Object)
wait the task is added to the waiting list
notify a randomly chosen task in the waiting list is moved
to the ready queue
notifyAll all waiting tasks are moved to the ready queue

public synchronized void deposit (int item)


while (filled == queueSize)
wait();
que[nextIn] = item;
nextIn = (nextIn % queueSize) + 1;
filled++;
notifyAll();
}

IA010 9. Concurrency 30
Java atomic variables

• classes in the java.util.concurrent.atomic package


(e.g. AtomicInteger)
• non-blocking, synchronized access to
• types int, long, boolean
• arrays
• references
• methods
• getters, setters and arithmetic operations
• cannot be interrupted (atomicity)
• advantages
• no need for locks
• efficient
• faster than using synchronized
• for int and long often atomic operations support in
hardware

IA010 9. Concurrency 31
Java atomic variables IIa
example

class Counter {
private int c = 0;

public void increment() {


c++;
}

public void decrement() {


c--;
}

public int value() {


return c;
}

IA010 9. Concurrency 32
Java atomic variables IIb
example

class SynchronizedCounter {
private int c = 0;

public synchronized void increment() {


c++;
}

public synchronized void decrement() {


c--;
}

public synchronized int value() {


return c;
}

IA010 9. Concurrency 33
Java atomic variables IIc
example
import java.util.concurrent.atomic.AtomicInteger;

class AtomicCounter {
private AtomicInteger c = new AtomicInteger(0);

public void increment() {


c.incrementAndGet();
}

public void decrement() {


c.decrementAndGet();
}

public int value() {


return c.get();
}

IA010 9. Concurrency 34
Java – explicit locks

Lock lock = new ReentrantLock();


...
Lock.lock();
try {
// The code that accesses the shared data
} finally {
Lock.unlock();
}

• an alternative to synchronized
• starting with Java 5.0
• class ReentrantLock, interface Lock
• methods lock, tryLock, unlock
• advantages (compared to synchronized):
• the tryLock method waits only for a specified time
• does not have to follow the nesting structure

IA010 9. Concurrency 35
Message passing

IA010 9. Concurrency 36
Message passing

• no relationship to message passing in OOP!


• Hansen (1978), Hoare (1978)
• nondeterminism is needed to achieve fairness
⇒ related to guarded commands
• message passing can be synchronous or asynchronous

synchronous message passing


• one of the tasks sends a message
• the other task must be ready to receive the message
• only then the communication takes place – rendezvous
• the information exchange can then go in both directions

IA010 9. Concurrency 37
Concurrency in Ada

• implemented by message passing


• basic concept: tasks
• syntactically simillar to packages (specification, body)
• can be a part of a package, a subroutine or a body
• interface: entry points
• part of the specification
• locations, where tasks can receive messages
• messages can be parameterized
• method body contains the corresponding accept clause
• here the received message is processed
• two specific types of tasks
• actor tasks – no entry points
• server tasks – no code outside accept clauses

IA010 9. Concurrency 38
Ada – syntax

Specification
task Task_Example is
entry Entry_1(Item : in Integer);
end Task_Example;

Implementation
task body Task_Example is
begin
loop
accept Entry_1(Item : in Integer) do
...
end Entry_1;
end loop;
end Task_Example;

IA010 9. Concurrency 39
Ada – the course of synchronization

IA010 9. Concurrency 40
Ada – choosing the recipient

• significant asymmetry
• the sending task must know the name of the entry point
• the receiving task receives from anybody
• multiple entry points per task?
• considered in the order they appear
• select clauses – in any order
select
accept Foo_Msg(formal parameters) do
...
end Foo_Msg;
...
or
accept Bar_Msg(formal parameters) do
...
end Bar_Msg;
...
end select;

IA010 9. Concurrency 41
Ada buffer example
task body Buf_Task is
Bufsize : constant Integer := 100;
Buf: array (1..Bufsize) of Integer;
Filled : Integer range 0..Bufsize := 0;
Next_In,Next_Out : Integer range 1..Bufsize := 1;
begin
loop
select
when Filled < Bufsize => -- open or closed
accept Deposit(Item : in Integer) do
Buf(Next_In) := Item;
end Deposit;
Next_In := (Next_In mod Bufsize) + 1;
Filled := Filled + 1;
or
when Filled > 0 => -- open or closed
accept Fetch(Item : out Integer) do
...
end Buf_Task;

IA010 9. Concurrency 42
Ada concurrency

there’s more . . .
• shared memory in addition to message passing
• tasks can be used to implement monitors,
but are much more general!
similar to the relationship between packages and ADTs

• prone to programming errors


• problems efficiently implementating rendezvous
• solution: protected objects
• similar to monitors
• entry points replaced by protected functions/procedures

IA010 9. Concurrency 43
Concurrency in functional
languages

IA010 9. Concurrency 44
Multilisp

pcall
(pcall f a b c d)

• parameters a,b,c,d of the function f can be evaluated


concurrently
• safe if there are no side-effects

future
(future x)

• creates a new task evaluating x


• the original task continues until it needs the value of x

IA010 9. Concurrency 45
Concurrent ML (CML)

• threads, created using spawn (function)


let val c : string chan = channel ()
in spawn (fn () => TextIO.print (recv c));

• the resulting value is ignored


• effects: output or communication with other threads
• inter-thread communication
• using channels
• synchronous message passing
• channels are types (can be passed as a parameter)
• if multiple messages, the choice among them is random

IA010 9. Concurrency 46

You might also like