Whats the problem Process thread1 { Process thread2 { foo = 1; foo - - PDF document

what s the problem
SMART_READER_LITE
LIVE PREVIEW

Whats the problem Process thread1 { Process thread2 { foo = 1; foo - - PDF document

Whats the problem Process thread1 { Process thread2 { foo = 1; foo = 3; Pthread Synchronization bar = 2; bar = 4; } } Operating Systems What are the possible results? Hebrew University Spring 2004 Race condition Atomic Updates


slide-1
SLIDE 1
  • Pthread Synchronization

Operating Systems Hebrew University Spring 2004

What’s the problem

Process thread1 { foo = 1; bar = 2; } Process thread2 { foo = 3; bar = 4; }

  • What are the possible results?

Race condition

  • Two threads racing to perform the same

task

  • Interleaving of operations can cause

incorrect behavior

Atomic Updates

  • Perform the following items as a single unit
  • When we are done, exactly (A or B) is true

– not (A and B) – not part of A and part of B

  • Critical Section!

Mutex

  • Enter and Exit critical

section

#include <pthread.h> int pthread_mutex_lock(mutex); int pthread_mutex_unlock(mutex);

mutex_var Thread A Thread B

lock block

var

access

No problem

Process thread1 { pthread_mutex_lock(l); foo = 1; bar = 2; pthread_mutex_unlock(l); } Process thread2 { pthread_mutex_lock(l); foo = 3; bar = 4; pthread_mutex_unlock(l); }

  • What are the possible results?
slide-2
SLIDE 2
  • What’s the problem?

Process producer { while(1) { while(count == 1) no_op; data = c; count = 1; } } Process consumer { while(1) { while(count == 0) no_op; c = data; count = 0; // consume c } }

Try it with a mutex One solution

Process producer { while(1) { lock(mutex); if (count == 0){ // produce c data = c; count = 1; } unlock(mutex); } } Process consumer { while(1) { lock(mutex); if (count == 1){ c = data; count = 0; } unlock(mutex); // consume c } }

  • Problems
  • Produce inside of lock
  • Starvation
  • Busy wait

Better solution

Process producer { while(1) { // produce c lock(empty); lock(mutex); data = c; unlock(mutex); unlock(full); } } Process consumer { while(1) { lock(full); lock(mutex); c = data; unlock(mutex); unlock(empty); // consume c } }

  • How many mutexs are in use?
  • What is the initial state of the mutexs?

Condition Signals

  • Wait on a condition
  • Associated with mutex

to prevent race condition

#include <pthread.h> pthread_mutex_t m; pthread_cond_t c; int pthread_cond_wait(&c, &m) int pthread_cond_signal(&c); int pthread_cond_broadcast(&c);

Solution using conditions

void producer() { int i = 1; while (1) { pthread_mutex_lock(&mutex); while (count == 1) { pthread_cond_wait(&control, &mutex); } data = i; count = 1; pthread_cond_signal(&control); pthread_mutex_unlock(&mutex); } void consumer() { int i = 0; while (1) { pthread_mutex_lock(&mutex); while (count == 0) { pthread_cond_wait(&control, &mutex); } i = data; count = 0; pthread_cond_signal(&control); pthread_mutex_unlock(&mutex); }

slide-3
SLIDE 3
  • Counting Mutex
  • Linux Extension
  • PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
  • A Partial Semaphore
  • Can be called recursively in a single thread
  • Counts number of calls and unlocks once count is zero

Error Checking Mutex

  • Linux Extension:
  • PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP;
  • If called recursively, return an error!
  • Very helpful for debugging deadlocks

Mutex Maintenance

  • int pthread_mutex_init(&m, &flags)
  • int pthread_mutex_trylock(&m);
  • int pthread_mutex_destroy(&m);

Condition Maintenance

  • PTHREAD_COND_INITIALIZER
  • int pthread_cond_init(&c)
  • int pthread_cond_timedwait(&c, &m, &t);
  • int pthread_cond_destroy(&c)

Problems with Solutions

  • Barrier

– Wait until all have registered – Wait until at least one has registered – Insure that a function is called exactly once

Two Phase locking

  • Get all the locks in a consistent order
  • Do the work
  • Release the locks in the inverse order
  • Reduces Deadlocks