170 likes | 369 Views
Pthreads. #include <pthread.h> #include <stdio.h> int sum ; //global data shared by all threads void *sum_dog (void *) ; //thread signature main(int argc, char *argv[]) { pthread_t tid ; // thread identifier
E N D
Pthreads #include <pthread.h> #include <stdio.h> int sum ; //global data shared by all threads void *sum_dog (void *) ; //thread signature main(int argc, char *argv[]) { pthread_t tid ; // thread identifier pthread_attr_t attr ; // set of attributes for the thread. E.g., stack size, scheduling //attributes, etc. pthread_attr_init (&attr) ; // get default attributes pthread_create(&tid, &attr, sum_dog, argv[1]) ; // create the thread. Now two //threads executing concurrently. compute_some_stuff() ; pthread_join (tid, NULL) ; //wait for thread to exit before continuing printf(“Sum_dog has spoken %d\n”, sum) ; }
void * sum_dog(void *param) { int puppy_upper, i; puppy_upper = atoi(param) ; //string to int. for (i= 0 ; i< puppy_upper ; i++) sum += i ; pthread_exit(0) ; }
Shared Data • All threads share: • Global variables • Static variables in function in which they are created. • Local variables are private to threads. • In program sum is shared by the main thread and the spawned thread. • Local variables i, and puppy_upper are private to the spawned thread.
Pthreads #include <pthread.h> #include <stdio.h> int sum ; //global data shared by all threads void *sum_dog (void *) ; //thread signature main(int argc, char *argv[]) { pthread_t tid, tid1 ; // thread identifier pthread_attr_t attr ; // set of attributes for the thread. E.g., stack size, scheduling //attributes, etc. pthread_attr_init (&attr) ; // get default attributes pthread_create(&tid, &attr, sum_dog, argv[1]) ; // create the thread. Now two pthread_create(&tid1, &attr, sum_dog, argv[1]) ; // create the thread. Now three //threads executing concurrently. compute_some_stuff() ; pthread_join (tid, NULL) ; //wait for thread to exit before continuing printf(“Sum_dog has spoken %d\n”, sum) ; }
void * sum_dog(void *param) { int puppy_upper, i; static int x = 0 ; puppy_upper = atoi(param) ; //string to int. for (i= 0 ; i< puppy_upper ; i++) sum += i ; pthread_exit(0) ; }
Pthread 2 Main Thread Pthread 1 CPU
Shared Among all Threads sum Sum_Dog Sum_Dog1 Main Thread Shared between thread functions. x Private copy for each Sum_Dog function. Puppy_Upper • i
Producer-Consumer Problem • Paradigm for cooperating processes (threads), producer process produces information that is consumed by a consumer process. • unbounded-buffer places no practical limit on the size of the buffer. • bounded-buffer assumes that there is a fixed buffer size.
Constraints • Do not over-write an item not yet consumed. • Do not write to a full buffer • Do not read from a previously read item. • Do not read from an empty buffer.
in = 1 ; counter = 1 Producer X Consumer out = 0
in = 2 ; counter = 2 Producer X X Consumer out = 0
in = 2 ; counter = 1 Producer x Consumer out = 1
in = 3 ; counter = 2 Producer x x Consumer out = 1
Thread-based Producer/Consumer #include <pthread.h> int counter = 0, BUFFER_SIZE = 10 ; /shared between threads void *Producer(void *NULL) int in = 0 ; while (1) { while (counter == BUFFER_SIZE) ; // do nothing, busy wait // produce an item and put in nextProduced buffer[in] = nextProduced; in = (in + 1) % BUFFER_SIZE; counter++; }
void *Consumer (void *NULL) { int out = 0 while (1) { while (counter == 0) ; // do nothing, busy wait nextConsumed = buffer[out]; out = (out + 1) % BUFFER_SIZE; counter--; // consume the item in nextConsumed } }
Executed Separately work as expected. • Execute concurrently, causes race condition.
Consider this execution interleaving: S0: producer execute register1 = counter {register1 = 5}S1: producer execute register1 = register1 + 1 {register1 = 6} S2: consumer execute register2 = counter {register2 = 5} S3: consumer execute register2 = register2 - 1 {register2 = 4} S4: producer execute counter = register1 {counter = 6 } S5: consumer execute counter = register2 {counter = 4} Preempted