Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
0% found this document useful (0 votes)
41 views

Lecture09 ConcurrentProgramming 02 Synchronization

The document discusses synchronization in concurrent programming. It covers shared variables and race conditions, and how to prevent them using mutual exclusion and locks. It also discusses critical sections, deadlocks, and using condition variables to signal between threads.

Uploaded by

doublefelix921
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
41 views

Lecture09 ConcurrentProgramming 02 Synchronization

The document discusses synchronization in concurrent programming. It covers shared variables and race conditions, and how to prevent them using mutual exclusion and locks. It also discusses critical sections, deadlocks, and using condition variables to signal between threads.

Uploaded by

doublefelix921
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 30

Concurrent Programming:

Synchronization
Computer Systems Organization (Spring 2016)
CSCI-UA 201, Section 2

Instructor: Joanna Klukowska

Slides adapted from


Randal E. Bryant and David R. OHallaron (CMU)
Randy Shepherd and Jinyang Li (NYU)

Race Example Revisited


int numbers[2] = { 1, 1 };
int sum = 0;
int main()
{
pthread_t tid;
pthread_create(&tid, 0, run, (void *)(numbers + 1));
for (int i = 0; i < 1; i++)
sum += numbers[i];
}
pthread_join(tid, 0);

What's the expected output?


2
but it could be 1

printf("sum is %d\n", sum);


return 0;
}
void* run(void* arg)
{
int* numbers = (int*) arg;
for (int i = 0; i < 1; i++)
{
sum += numbers[i];
}
return 0;
}
2

Race Example cont


Why can the outcome be 1? This line is the culprit.

What does this look like in assembly?

Two threads T, T' have combinatorial number of interleavings


OK: T1, T2, T3, T4, T'1, T'2, T'3, T'4
BAD: T1, T'1, T2, T'2, T3, T'3, T4, T'4

Global variable sum is written as 1 by both threads at T4 & T'4


3

The Source of the Problem?


What was the source of the race condition. What was being accessed by
multiple threads, leading to incorrect results?
sum, a global variable shared between threads

Ok, the solution is not to share variables across threads, right?


Global variables are bad anyway.

Not so fast
Sharing variables is actually useful thing when programming threads
Global variables are not the only variable type that can be shared.

Shared Variables in Threaded C Programs


Question: Which variables in a threaded C program are shared?
The answer is not as simple as global variables are shared and
stack variables are private

Definition of a shared variable


A variable x is shared if multiple threads reference some instance of x.

Requires answers to the following questions:


What is the memory model for threads?
Where are instances of variables stored in memory?
How many threads might reference each of these instances?

Threads Memory Model


Conceptual model:
Multiple threads run within the context of a single process
Each thread has its own separate thread context
Thread ID, stack, stack pointer, PC, condition codes, and GP registers
All threads share the remaining process context
Code, data, heap & shared library segments of the process address space

Operationally, this model is not strictly enforced:


Register values are truly separate and protected, but
Any thread can read and write the stack of any other thread

The mismatch between the conceptual and operational model


is a source of confusion and errors
6

Example of Sharing

Peer threads reference main threads stack


indirectly through global ptr variable

Mapping Variable Instances to Memory


Global variables
Definition: Variable declared outside of a function
Virtual memory contains exactly one instance of any global variable

Local variables
Definition: Variable inside function without static attribute
Each thread stack contains one instance of each local variable

Local static variables


Definition: Variable inside function with static attribute
Virtual memory contains exactly one instance of any local static variable.

Mapping Variable Instances to Memory


Global var: 1 instance (ptr .bss section)
Local vars: 1 instance (main.i, main.msgs)
Local var: 2 instances (
p0.i [peer thread 0s stack],
p1.i [peer thread 1s stack]
)

Local static var: 1 instance (cnt .data section)

Shared Variable Analysis


Which variables are shared?
Variable
instance

ptr
cnt
main.i
main.msgs
p0.i
p1.i

Referenced by
main thread?

yes
no
yes
yes
no
no

Referenced by
peer thread 0?

yes
yes
no
yes
yes
no

Referenced by
peer thread 1?

yes
yes
no
yes
no
yes

Answer: A variable x is shared if multiple threads


reference at least one instance of x. Thus:
ptr, cnt, and msgs are shared
*.i are not shared
10

Synchronizing Threads
Shared variables are sometimes useful but they introduce the
possibility of synchronization errors.
Like the one we saw last time

How do we prevent such things?


We need to make sure that only one thread is mutating shared variables at a
time.
This is known as mutual exclusion

Moreover, we must protect critical sections.

11

Critical Sections (CS)


A critical section is a part of a multi-threaded program that must
not be concurrently executed by more than one of the program's
threads.
Critical sections access shared variables that are not safe for
concurrent accesses.
Critical sections must be protected
Must make sure accesses within a CS are not interleaved.
Or equivalently, CS must have atomicity
Atomicity is achieved via mutual exclusion.

12

Mutual Exclusion
A mutex
is synchronization variable that is used to protect the access to shared variables.
surrounds critical sections so that one threads is allowed inside at a time.

In practice, you (mentally) associates a mutex with a set of shared


variables

13

Pthread Lock Functions


There are three basic operations defined on a mutex.
pthread_mutex_init(pthread_mutex_t *mutex, ..)
Initializes the specified mutex to its default values
The second argument will always be NULL for us
pthread_mutex_lock(pthread_mutex_t *mutex)
Acquires a lock on the specified mutex variable.
If the mutex is already held by another thread, this call will block the
calling thread until the mutex is unlocked.
pthread_mutex_unlock(pthread_mutex_t *mutex)
Unlocks a mutex variable.
An error is returned if mutex is already unlocked.

14

Example Critical Section


If no synchronization, what
happens when there are two
concurrent calls with the
same argument values?

T1: read account x = 100


T2: read account x = 100
T1: write account x = 90
T2: write account x = 90
T1: read account y = 100
T1: increment account y = 110
T2: read account y = 110
T2: increment account y = 120

15

The Easy Solution


Put a mutex around the critical
section in the transfer function
The lock is associated with the
array accounts.
In the programmers head, at least.

Are there any drawbacks to this


approach?

See mutex.c for another


example.

16

Problem with the Easy Solution


There is a problem here
coarse-grained locking
no concurrency
only one transfer happening at a
time.

17

Fine-grained Locking

18

Fine-grained Locking cont


Looks good! Right?

Then why did my entire


banking system just stop
functioning?
Hmmm.. looking at the
system logs I see this
T1:transfer(X,Y, 10)
T2:transfer(Y,X, 20)

19

Deadlock
The following series of instructions happened

T1: acquired X's lock


T2: acquired Y's lock
T1: blocked waiting for Y's lock to be released
T2: blocked waiting for X's lock to be released

Neither can make progress! This is known as deadlock


A deadlock is any situation in which two or more competing
actions are each waiting for the other to finish, and thus none
ever do.

20

Deadlock cont
Both processes need resources to continue execution.
P1 requires additional resource R1 and is in possession of
resource R2
P2 requires additional resource R2 and is in possession of R1;
neither process can continue.

21

Dining Philosophers

Five philosophers
Goal in life: eat, think, eat,
think, eat, think, ...
Five bowls of spaghetti
Five forks
But need two forks to eat

Will they all starve or live for ever?

See Wikipedia article: https://en.wikipedia.


org/wiki/Dining_philosophers_problem

22

Solution to the deadlock problem


Acquire locks in the order based on account number

This approach works in general.

23

Condition Variables
Locking is a simple kind of resource scheduling -- one thread at a time
may enter a critical section.
What about more complicated scheduling policy?
Supposed we need a mechanism to block thread(s) until some condition is true?

Condition variables are synchronization variables that are used for


signaling that some condition is met and that any waiting threads can
proceed.

24

Waiting on a Condition
For example, suppose we want one function in one thread to produce a
value and another function on another thread to consume that value?

25

Pthread Condition Variable Functions


Pthreads defines three basic operations on condition variables.
int pthread_cond_init(cond, )
Takes two arguments, the first of which is the condition variable itself. The
second we dont care about.
int pthread_cond_wait(cond, mutex)
The calling thread will wait until the condition represented by the cond variable
is met.
int pthread_cond_signal(cond)
Sends a signal that wakes up exactly one thread that is waiting due to a call to
pthread_cond_wait.

26

Condition Variable Example

27

Conditional Variable Usage

The general pattern is


T1:
lock(&m);
while (condition != true)
cond_wait(&cv, &m)
... do stuff...
unlock(&m)
T2:
lock(&m)
condition = true
cond_signal(&cv)
unlock(&m)
28

Another Conditional Variable Example

See cond_var.c

29

Summary

Programmers need a clear model of how variables are shared


by threads.

Variables shared by multiple threads must be protected to


ensure mutually exclusive access.

Mutexes are a fundamental mechanism for enforcing mutual


exclusion.

Conditional variables can be used to signal between threads


that some condition has been met.

30

You might also like