race condition
play

Race Condition Shared Data: 4 5 6 1 8 5 6 20 9 ? - PDF document

Race Condition Shared Data: 4 5 6 1 8 5 6 20 9 ? Synchronization and Deadlocks tail A[] (or The Dangers of Threading) Enqueue(): A[tail] = 20; A[tail] = 9; Jonathan Misurda tail++; tail++; thread jmisurda@cs.pitt.edu switch


  1. Race Condition Shared Data: 4 5 6 1 8 5 6 20 9 ? Synchronization and Deadlocks tail A[] (or The Dangers of Threading) Enqueue(): A[tail] = 20; A[tail] = 9; Jonathan Misurda tail++; tail++; thread jmisurda@cs.pitt.edu switch Thread 0 Thread 1 Critical Regions Synchronization • Scheduling can be random and preemption can happen at any time Enters Leaves critical region critical region • Need some way to make critical regions Thread 0 Leaves “atomic” Enters Tries to enter critical region critical region critical region Thread 1 B blocked • Need help from the Operating System Time Mutex Critical Sections Shared Data: • MUTual EXclusion 4 tail 5 6 1 8 5 6 20 9 • A mutex is a lock that only one thread can A[] mutex acquire • All other threads attempting to enter the Blocked! Enqueue(): critical region will be blocked lock(&mutex); lock(&mutex); A[tail] = 20; A[tail] = 9; thread switch tail++; tail++; unlock(&mutex); unlock(&mutex); Thread 0 Thread 1

  2. pthread_mutex_t Producer/Consumer Problem Shared variables #include <stdio.h> #define N 10; #include <pthread.h> int buffer[N]; int in = 0, out = 0, counter = 0; int tail = 0; Producer Consumer int A[20]; while (1) { while (1) { pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; if (counter == N) if (counter == 0) sleep(); sleep(); void enqueue(int value) buffer[in] = ... ; ... = buffer[out]; { in = (in+1) % N; out = (out+1) % N; pthread_mutex_lock(&mutex); counter++; counter ‐‐ ; A[tail] = value; tail++; if (counter==1) if (count == N ‐ 1) pthread_mutex_unlock(&mutex); wakeup(consumer); wakeup(producer); } } } Deadlocks Condition Variables • “A set of processes is deadlocked if each • A condition under which a thread executes or process in the set is waiting for an event that is blocked only another process in the set can cause.” • pthread_cond_t • Caused when: 1. Mutual exclusion • pthread_cond_wait (condition, mutex) 2. Hold and wait • pthread_cond_signal (condition) 3. No preemption of resource 4. Circular wait Producer/Consumer Semaphores #define N 10 int buffer[N]; int counter = 0, in = 0, out = 0, total = 0; • A lock that remembers “missed” wakeups pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; pthread_cond_t prod_cond = PTHREAD_COND_INITIALIZER; pthread_cond_t cons_cond = PTHREAD_COND_INITIALIZER; • Mutexes are a special case of Semaphores void *producer(void *junk) { void *consumer(void *junk) { while(1) { while(1) { that only count to 1 pthread_mutex_lock(&mutex); pthread_mutex_lock(&mutex); if( counter == N ) pthread_cond_wait(&prod_cond, if( counter == 0 ) &mutex); pthread_cond_wait(&cons_cond, &mutex); buffer[in] = total++; printf("Produced: %d\n", printf("Consumed: %d\n", buffer[in]); buffer[out]); in = (in + 1) % N; out = (out + 1) % N; counter++; counter ‐‐ ; if( counter == 1 ) if( counter == (N ‐ 1) ) pthread_cond_signal(&cons_cond); pthread_cond_signal(&prod_cond); pthread_mutex_unlock(&mutex); pthread_mutex_unlock(&mutex); } } } }

  3. Producer/Consumer Producer/Consumer #include <semaphore.h> #include <semaphore.h> #define N 10 #define N 10 int buffer[N]; int buffer[N]; int counter = 0, in = 0, out = 0, total = 0; int counter = 0, in = 0, out = 0, total = 0; pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; sem_t semmutex; // sem_init(&semmutex, 0, 1); in main() sem_t semfull; // sem_init(&semfull, 0, 0); in main() sem_t semfull; // sem_init(&semfull, 0, 0); in main() sem_t semempty; // sem_init(&semempty, 0, N); in main() sem_t semempty; // sem_init(&semempty, 0, N); in main() void *producer(void *junk) { void *consumer(void *junk) { void *producer(void *junk) { void *consumer(void *junk) { while(1) { while(1) { while(1) { while(1) { sem_wait(&semempty); sem_wait(&semfull); sem_wait(&semempty); sem_wait(&semfull); pthread_mutex_lock(&mutex); pthread_mutex_lock(&mutex); sem_wait(&semmutex); sem_wait(&semmutex); buffer[in] = total++; printf("Consumed: %d\n", buffer[in] = total++; printf("Consumed: %d\n", printf("Produced: %d\n", buffer[out]); printf("Produced: %d\n", buffer[out]); buffer[in]); out = (out + 1) % N; buffer[in]); out = (out + 1) % N; in = (in + 1) % N; counter ‐‐ ; in = (in + 1) % N; counter ‐‐ ; counter++; counter++; pthread_mutex_unlock(&mutex); pthread_mutex_unlock(&mutex); sem_post(&semmutex); sem_post(&semmutex); sem_post(&semfull); sem_post(&semempty); sem_post(&semfull); sem_post(&semempty); } } } } } } } } Deadlock! #include <semaphore.h> #define N 10 int buffer[N]; int counter = 0, in = 0, out = 0, total = 0; sem_t semmutex; // sem_init(&semmutex, 0, 1); in main() sem_t semfull; // sem_init(&semfull, 0, 0); in main() sem_t semempty; // sem_init(&semempty, 0, N); in main() void *producer(void *junk) { void *consumer(void *junk) { while(1) { while(1) { sem_wait(&semmutex); sem_wait(&semmutex); sem_wait(&semempty); sem_wait(&semfull); buffer[in] = total++; printf("Consumed: %d\n", printf("Produced: %d\n", buffer[out]); buffer[in]); out = (out + 1) % N; in = (in + 1) % N; counter ‐‐ ; counter++; sem_post(&semfull); sem_post(&semempty); sem_post(&semmutex); sem_post(&semmutex); } } } }

Download Presentation
Download Policy: The content available on the website is offered to you 'AS IS' for your personal information and use only. It cannot be commercialized, licensed, or distributed on other websites without prior consent from the author. To download a presentation, simply click this link. If you encounter any difficulties during the download process, it's possible that the publisher has removed the file from their server.

Recommend


More recommend