/
CS252: Systems Programming CS252: Systems Programming

CS252: Systems Programming - PowerPoint Presentation

rouperli
rouperli . @rouperli
Follow
343 views
Uploaded On 2020-06-23

CS252: Systems Programming - PPT Presentation

Ninghui Li Based on Slides by Prof Gustavo RodriguezRivera Topic 11 Threads and Thread Synchronization Clicker Question 1 from MidTerm Consider the following yacc code list NUMBER ID: 783740

counter mutex amp threads mutex counter threads amp lock thread int pthread tmp locks max synchronization 000 list code

Share:

Link:

Embed:

Download Presentation from below link

Download The PPT/PDF document "CS252: Systems Programming" is the property of its rightful owner. Permission is granted to download and print the materials on this web site for personal, non-commercial use only, and to display it on your personal computer provided you do not modify the materials and that you retain all copyright notices contained in the materials. By downloading content from our website, you accept the terms of this agreement.


Presentation Transcript

Slide1

CS252: Systems Programming

Ninghui Li

Based on Slides by Prof. Gustavo

Rodriguez-Rivera

Topic 11:

Threads and Thread Synchronization

Slide2

Clicker Question 1

from Mid-Term

Consider the following

yacc code:list : NUMBER { numbers[0] = $1; $$ = 1;} | list CM NUMBER { $$ = $1 + 1; if ($1<MAX_LENGTH) numbers[$1] = $3; }

When parsing

[2, 3, -1, 4]

When “list: NUMBER”

is used, what is value of $1?

0

1

2

3

None of the above

Slide3

Clicker Question 2

from Mid-Term

Consider the following

yacc code:list : NUMBER { numbers[0] = $1; $$ = 1;} | list CM NUMBER { $$ = $1 + 1; if ($1<MAX_LENGTH) numbers[$1] = $3; }

When parsing

[2, 3, -1, 4]

How many times is

“list: list CM NUMBER”

Used?

1

2

3

4

None of the above

Slide4

Clicker Question 3

from Mid-Term

Consider the following

yacc code:list : NUMBER { numbers[0] = $1; $$ = 1;} | list CM NUMBER { $$ = $1 + 1; if ($1<MAX_LENGTH) numbers[$1] = $3; }

When parsing

[2, 3, -1, 4]

At the second time

“list: list CM NUMBER”

is used, ($1,$3)=

(2,3)

(3,-1)

(3,4)

(2,4)

None of the above

Slide5

Clicker Question 4

from Mid-term Exam

(

define (foo x y) (ifz x y (ifz y x (inc (foo (dec x) (dec y))))))What is the value of (foo 2 4)?0123

None of the above

Slide6

Clicker Question 5

from Mid-Term

Consider the following code for the C programming question:

struct queue * new_queue() { struct queue *q = (struct queue*) malloc(sizeof(struct queue)); q->head = NULL; q->tail = NULL; return q;}void enqueue (struct queue *q, char *v) { struct node *nd = (struct node*)

malloc

(

sizeof

(struct

node));

nd

->value = v;

if (q->tail == NULL) { q->tail = nd; q->head = nd; } else { q->tail = nd; }}

How many bugs there are in

enqueue

?

0

1

2

3

4 or more

Slide7

Introduction to Threads

A thread is a path execution

By default, a C/C++ program has one thread called "main thread" that starts the main() function.

main() --- --- printf( "hello\n" ); ---}

Slide8

Introduction to Threads

You can create multiple paths of execution using:

POSIX threads ( standard )

pthread_create( &thr_id, attr, func, arg )WindowsCreateThread(attr, stack_size, func, arg, flags, &thr_id)

Slide9

Introduction to Threads

Every thread will have its own

Stack

PC – Program counterSet of registersStateThis information is stored in entry corresponding to the process in the process table entryEach thread will have its own function calls, and local variables.

Slide10

Memory Layout of Threads

A single-threaded process

A process with two threads

Slide11

Applications of Threads

Concurrent Server applications

Assume a web server that receives two requests:

First, one request from a computer connected through a modem that will take 2 minutes. Then another request from a computer connected to a fast network that will take .01 secs. If the web server is single threaded, the second request will be processed only after 2 minutes.In a multi-threaded server, two threads will be created to process both requests simultaneously. The second request will be processed as soon as it arrives.

Slide12

Application of Threads

Taking Advantage of Multiple CPUs

A program with only one thread can use only one CPU. If the computer has multiple cores, only one of them will be used.

If a program divides the work among multiple threads, the OS will schedule a different thread in each CPU.This will make the program run faster.

Slide13

Applications of Threads

Interactive Applications.

Threads simplify the implementation of interactive applications that require multiple simultaneous activities.

Assume an Internet telephone application with the following threads:Player thread - receives packets from the internet and plays them.Capture Thread – captures sound and sends the voice packetsRinger Server – Receives incoming requests and tells other phones when the phone is busy.Having a single thread doing all this makes the code cumbersome and difficult to read.

Slide14

Advantages and Disadvantages of Threads vs. Processes

Advantages of Threads

Fast thread creation

- creating a new path of execution is faster than creating a new process with a new virtual memory address space and open file table.Fast context switch - context switching across threads is faster than across processes.Fast communication across threads – threads communicate using global variables that is faster and easier than processes communicating through pipes or files.

Slide15

Advantages and Disadvantages of Threads vs. Processes

Disadvantages of Threads

Threads are less robust than processes

– If one thread crashes due to a bug in the code, the entire application will go down. If an application is implemented with multiple processes, if one process goes down, the other ones remain running.Threads have more synchronization problems – Since threads modify the same global variables at the same time, they may corrupt the data structures. Synchronization through mutex locks and semaphores is needed for that. Processes do not have that problem because each of them have their own copy of the variables.

Slide16

Synchronization Problems with Multiple Threads

Threads share same global variables.

Multiple threads can modify the same data structures at the same time

This can corrupt the data structures of the program.Even the most simple operations, like increasing a counter, may have problems when running multiple threads.

Slide17

Example of Problems with Synchronization

// Global counter

int

counter = 0;void increment_loop(void *arg){ int i; int max = * ((int *)arg); for(i=0;i<max;i++){ int

tmp

= counter;

tmp

=tmp+1;

counter=

tmp

;

}

}

Slide18

Example of Problems with Synchronization

int

main(){

pthread_t t1,t2; int max = 10000000; void *ret; pthread_create(&t1,NULL, increment_loop,(void*)&max); pthread_create(&t2,NULL, increment_loop,(void*)&max);

//wait until threads finish

pthread_join

(t1, &ret);

pthread_join

(t2, &ret);

printf

(“counter total=%

d”,counter);}

Slide19

Example of Problems with Synchronization

We would expect that the final value of counter would be

10,000,000+ 10,000,000= 20,000,000

but very likely the final value will be less than that (E.g. 12804354).The context switch from one thread to another may change the sequence of events so the counter may loose some of the counts.

Slide20

Example of Problems with Synchronization

int counter = 0;

void increment_loop(int max){

for(int i=0;i<max;i++){ a)int tmp= counter; b)tmp=tmp+1; c)counter=tmp; }}T2int counter = 0;void increment_loop(int max){

for(int i=0;i<max;i++){

a)int tmp = counter;

b)tmp=tmp+1;

c)counter=tmp;

}

}

T1

Slide21

Example of Problems with Synchronization

T1

T2

T0 (main)for(…)a)tmp1=counter (tmp1=0)(Context switch)

Join t1

(wait)

Starts running

a)tmp2=counter

(tmp2=0)

b)tmp2=tmp2+1

c)counter=tmp2

Counter=1

a)b)c)a)b)c)…

Counter=23

(context switch)

b)tmp1=tmp1+1

c)counter=tmp1

Counter=1

time

Slide22

Example of Problems with Synchronization

As a result 23 of the increments will be lost.

T1 will reset the counter variable to 1 after T2 increased it 23 times.

Even if we use counter++ instead of a)b) c) we still have the same problem because the compiler will generate separate instructions that will look like a)b)c).Worse things will happen to lists, hash tables and other data structures in a multi-threaded program.The solution is to make certain pieces of the code Atomic.

Slide23

Atomicity

Atomic Section:

A portion of the code

that needs to appear to the rest of the system to occur instantaneously.Otherwise corruption of the variables is possible. An atomic section is also called sometimes a “Critical Section”

Slide24

Atomicity by disabling interrupts

On

uni

-processor, operation is atomic as long as context switch doesn’t occur during operationTo achieve atomicity: disable interrupts upon entering atomic section, and enable upon leavingContext switches cannot happen with interrupt disabled.Available only in kernel mode; thus only used in kernel programmingOther interrupts may be lost.Does not provide atomicity with multiprocessor

Slide25

Achieving Atomicity in Concurrent Programs

Our main goal is to learn how to write concurrent programs using synchronization tools

We also explain a little bit how these tools are implemented

Concurrent ProgramHigh-level synchronization tools (mutex locks, semaphores, condition variables, read/write locks)Hardware support (interrupt disable/enable, test & set, and so on)

Slide26

Atomicity by Mutex Locks

Mutex

Locks

are software mechanisms that enforce atomicityOnly one thread can hold a mutex lock at a timeWhen a thread tries to obtain a mutex lock that is held by another thread, it is put on hold (aka put to sleep, put to wait, blocked, etc).The thread may be waken up when the lock is available to the thread.Think of it as a locker in a gym with a lock and a key on it.

Slide27

Mutex Locks Usage

Declaration

:

#include <pthread.h>pthread_mutex_t mutex;Initializepthread_mutex_init( &mutex, atttributes);Start atomic sectionpthread_mutex_lock(&mutex);End atomic sectionpthread_mutex_unlock(&mutex);

Slide28

Example of Mutex Locks

#include <

pthread.h

>int counter = 0; // Global counterpthread_mutex_t mutex;void increment_loop(int max){ for(int i=0;i<max;i++){ pthread_mutex_lock(&mutex); int tmp = counter;

tmp

=tmp+1;

counter=

tmp

;

pthread_mutex_unlock

(&

mutex

); }}Threads

Slide29

Example of Mutex Locks

int main(){

pthread_t t1,t2;

pthread_mutex_init(&mutex,NULL); pthread_create(&t1,NULL, increment,10000000); pthread_create(&t2,NULL, increment,10000000); //wait until threads finish pthread_join(&t1); pthread_join(&t2); printf(“counter total=%d”,counter);}

Slide30

Example of Mutex Locks

T1

T2T0 (main)for(…)mutex_lock(&m) a)tmp1=counter (tmp1=0)

(Context switch)

Join t1

(wait)

Starts running

mutex_lock(&m)

(wait)

(context switch)

b)tmp1=tmp1+1

c)counter=tmp1

Counter=1

mutex_unlock(&m)

a)tmp2=counter

b)tmp2=tmp2+1

c)counter=tmp2

time

Slide31

Example of Mutex Locks

As a result, the steps a),b),c) will be atomic so the final counter total will be

10,000,000+ 10,000,000= 20,000,000

no matter if there are context switches in the middle of a)b)c)

Slide32

Mutual Exclusion

Mutex

Locks

enforce the mutual exclusion of all code between lock and unlockMutex_lock(&m)ABCMutex_unlock(&m)Mutex_lock(&m)DEFMutex_unlock(&m)

Slide33

Mutual Exclusion

This means that the sequence ABC, DEF, can be executed as an atomic block without interleaving.

Time ------------------------>

T1 -> ABC ABCT2 -> DEF DEFT3 -> ABC DEF

Slide34

Mutual Exclusion

If different

mutex

locks are used (m1!=m2) then the sections are no longer atomicABC and DEF can interleaveMutex_lock(&m1)ABCMutex_unlock(&m1)Mutex_lock(&m2)DEFMutex_unlock(&m2)

Slide35

Test_and_set

There is an instruction

test_and_set

that atomically set a variable to a certain value, and return its original valuePseudocode: int test_and_set(int *v){ int oldval = *v; *v = 1; return oldval; }This instruction is implemented by the CPU. You don’t need to implement it.

Slide36

Implementing Mutex Locks using Test and Set (pseudo code)

mutex_lock

(

mutex) { while (test_and_set (&mutex.m) != 0); if (mutex.lock) { mutex.queue( currentThread)); mutex.m = 0;

setWaitState

();

pthread_yield

();

} else{

mutex.lock

= true; mutex.m = 0; }}The

mutex

has the following fields:

lock

indicates whether the

mutex

has been locked by some thread

queue

stores all threads that are waiting for the

mutex

m

ensures that only one thread is performing update to lock & queue

Implements a busy-wait lock (aka spin lock).

Slide37

Implementing Mutex Locks using Test and Set (pseudo code)

mutex_unlock

() {

while (test_and_set (&mutex.m) != 0); if (mutex.queue. nonEmpty) { t=mutex.dequeue(); t.setReadyState(); } else { mutex.lock=false; }

mutex.m

= 0;

}

If some thread is waiting, get the first thread ready to run, keep the

mutex

locked, because now this thread holds the

mutex

.

Implements a busy-wait lock (aka spin lock).

Slide38

Review Questions

What does the system need to maintain for each thread?

Why one wants to use multiple threads?

What are the pros and cons of using threads vs. processes?What is an atomic section? Why disabling interrupt ensures atomicity on a single CPU machine?

Slide39

Review Questions

What is the meaning of the “test and set” primitive?

What is a

mutex lock? What is the semantics of lock and unlock calls on a mutex lock?How to use mutex locks to achieve atomicity?The exam does not require implementation of mutex lock.