1 / 35

PRODUCER CONSUMER PROBLEM

PRODUCER CONSUMER PROBLEM. Prepared By Sarath S Menon S6 CSE. Imagine a scenario in which there exists two Distinct processes both operating on a single shared data area.

hedia
Download Presentation

PRODUCER CONSUMER PROBLEM

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. PRODUCER CONSUMER PROBLEM Prepared By Sarath S Menon S6 CSE

  2. Imagine a scenario in which there exists two Distinct processes both operating on a single shared data area. • One process, the Producer inserts information into the data area whilst the other process, the Consumer, removes information from that same area. • In order for the Producer to insert information into the data area, there must be enough space. The Producer's sole function is to insert data into the data-area, it is not allowed to remove any data from the area. • Similarly, for the Consumer to be able to remove information from the data area, there must be information there in the first place. Once again, the sole function of the Consumer is to remove data from the data area. If no data is present then the Consumer is not allowed to insert some data of it's own to later be removed by itself. T90

  3. In computer science, the producer-consumer problem (also known as the bounded-buffer problem) is a classical example of a multi-process synchronization problem. • The problem describes two processes, the producer and the consumer, who share a common, fixed-size buffer. • The producer's job is to generate a piece of data, put it into the buffer and start again. • At the same time the consumer is consuming the data (i.e. removing it from the buffer) one piece at a time. • The problem is to make sure that the producer won't try to add data into the buffer if it's full and that the consumer won't try to remove data from an empty buffer. T90

  4. The solution for the producer is to go to sleep if the buffer is full. • The next time the consumer removes an item from the buffer, it wakes up the producer who starts to fill the buffer again. In the same way, the consumer goes to sleep if it finds the buffer to be empty. • The next time the producer puts data into the buffer, it wakes up the sleeping consumer. The solution can be reached by means of inter-process communication, typically using semaphores. • An inadequate solution could result in a deadlock where both processes are waiting to be awakened. The problem can also be generalized to have multiple producers and consumers T90

  5. MUTEX • Mutexesare good for managing mutual exclusion to some shared resource or piece of code. A mutex is a variable that can be in one of two states, unlocked or locked. • Consequently only one bit is required to represent it, but in practice an integer is often used with 0 meaning unlocked and all other values meaning locked. • Two procedures are used with mutexes. When a thread or a process needs access to a critical region, it calls mutex_lock. If the mutex is currently unlocked (maning the critical region is available) , the call succeeds and the calling thread is free to enter the critical region. T90

  6. On the other hand, if the mutex is already locked, the calling thread is blocked, until the thread in the critical region is finished and calls mutex unlock. If multiple threads are blocked on the mutex, one of them is chosen at random and allowed to aquire the lock. • Initialization Set full buffer slots to 0.    i.e., semaphore Full = 0. Set empty buffer slots to N.    i.e., semaphore empty = N. For control access to critical section set mutex to 1.    i.e., semaphore mutex = 1. T90

  7. Consumer ( ) • {WHILE (true) {        P (full)        P (mutex);        remove-Item ( );        V (mutex);        V (empty);        consume-Item (Item) • } • } • Producer ( ) {WHILE (true)  {produce-Item ( );        P (empty);        P (mutex);        enter-Item ( )        V (mutex)        V (full); } } T90

  8. T90

  9. T90

  10. Imagine… • A person is moving(shifting) to a new house. • Has a truck full of boxes to unload and carry. • Truck is on road, so boxes have to be first unloaded to the road and then carried to the house. • No one else is currently available to help T90

  11. Person 1 does all work by himself… • Takes a lot of time and effort, but very less quantity moved. • Calls a friend to help • Work is split • One person takes boxes off the truck and line them up on the Road. • Other takes boxes off the Road and take them into house. T90

  12. Plan works very well, work went at a fast rate. Until….. • A friend of the person on truck arrives to help. • Unloading takes place at a faster rate, the other person was unable to manage… • The person on road calls his friends… T90

  13. But the new helpers were not as helpful as expected!!! T90

  14. Sometimes the still outpace the consumers, the Road is full and the guys have to stand around holding boxes • Sometimes the consumers outpace the producers and they're standing around the Road instead of unpacking in house T90

  15. So everyone makes a rule: • check the road before you go there! • Unfortunately, it didn't help. • Paul and Peter, emptying opposite ends of the truck, both saw an almost full road, but clearly enough space for one more box. • So they both picked off a box, walked over, then bonked into each other (race condition!). T90

  16. Finally a new idea shows up. It has three new rules: • Person on truck : both have to check with me to make sure there's an empty spot before you drop-off • Others below have to check with the person who made the idea to make sure there's a box before they pick up • And finally, because there's only one observer, he/she can't keep track of this if more than one guy is messing with the line. • So even if there is a green light in step 1 or 2, they still need to check to make sure no one else is on the line. T90

  17. New Rules… • People on truck: waitFor(spaceOnRoad) waitFor(permissionToUseRoad) dropBoxOnRoad(box) nowSomeoneElseCanUse(permissionToUseRoad) nowSomeoneElseCanUse(boxesOnRoad) • Others: • complementary T90

  18. Algorithm Step 1: Set maximum buffer size, maximum producer and consumer threads. Step 2: Read buffer size, number of producer and consumer threads from the user. Step 3: Initialize the threads and set concurrency to the sum of both threads. Step 4: Start the threads. For producer thread, use produce() and for consumer, consume(). Step 5: Wait for all the threads to complete. Step 6: Print the number of items produced by each producer thread. Step 7: Print the number of items consumed by each consumer thread. Step 8: Print the number of items remaining in the buffer. T90

  19. In the produce() function, do: Step 1: Lock the mutex for the buffer. Step 2: If the buffer has reached the limit, unlock and stop. Step 3: Else, write to the next location in the buffer, and increment the location counter. Step 4: Increment p_count[i] for that thread, and unlock. T90

  20. In the consume() function, do: Step 1: Lock the mutex. Step 2: Check for the first written location. Step 3: If it is the end of buffer, unlock and stop. Else, read the item and set that location to EMPTY. Step 4: Increment c_count[i] for that thread, and unlock. T90

  21. Important Functions Used • sem_init • sem_post • sem_wait • sem_destroy • pthread_create T90

  22. sem_init • sem_init() • Initialize an unnamed semaphore • Synopsis: #include <semaphore.h> intsem_init( sem_t * sem, intpshared, unsigned value ); T90

  23. Sem • A pointer to the sem_t object for the semaphore that you want to initialize. • pshared • Nonzero if you want the semaphore to be shared between processes via shared memory. • value • The initial value of the semaphore. A positive value (i.e. greater than zero) indicates an unlocked semaphore, and a value of 0 (zero) indicates a locked semaphore. This value must not exceed SEM_VALUE_MAX. T90

  24. Library: • libc • Use the -l c option to gcc to link against this library. • This library is usually included automatically. T90

  25. You can use the initialized semaphore in subsequent calls to sem_wait(), sem_trywait(), sem_post(), and sem_destroy(). • An initialized semaphore is valid until it's destroyed by the sem_destroy() function, or until the memory where the semaphore resides is released. • If the pshared argument is nonzero, then the semaphore can be shared between processes via shared memory. • Any process can then use sem with the sem_wait(), sem_trywait(), sem_post() and sem_destroy() functions. T90

  26. Return Value • 0 • Success. • The semaphore referred to by sem is initialized. • -1 • An error occurred (errno is set). T90

  27. sem_post() • Increment a named or unnamed semaphore • Synopsis : #include <semaphore.h> int sem_post( sem_t * sem ); • sem • A pointer to the sem_t object for the semaphore whose value you want to increment. T90

  28. The sem_post() function increments the semaphore referenced by the sem argument. If any processes are currently blocked waiting for the semaphore, then one of these processes will return successfully from its call to sem_wait. • The process to be unblocked is determined in accordance with the scheduling policies in effect for the blocked processes. The highest priority waiting process is unblocked, and if there is more than one highest priority process blocked waiting for the semaphore, then the highest priority process that has been waiting the longest is unblocked. • The sem_post() function is reentrant with respect to signals, and can be called from a signal handler. T90

  29. Return Value • 0 • Success. • -1 • An error occurred (errno is set). T90

  30. sem_wait() • Wait on a named or unnamed semaphore Synopsis: #include <semaphore.h> intsem_wait( sem_t * sem); • sem • A pointer to the sem_t object for the semaphore that you want to wait on. T90

  31. The sem_wait() function decrements the semaphore referred to by the sem argument. If the semaphore value is not greater than zero, then the calling process blocks until it can decrement the counter, or the call is interrupted by signal. • Some process should eventually call sem_post() to increment the semaphore. T90

  32. Return Value • 0 • The semaphore was successfully decremented. • -1 • The state of the semaphore is unchanged (errno is set). T90

  33. sem_destroy() • Destroy a semaphore Synopsis: #include <semaphore.h> intsem_destroy( sem_t * sem); • sem • A pointer to the sem_t object for the semaphore that you want to destroy. T90

  34. The sem_destroy() function destroys the unnamed semaphore referred to by the sem argument. The semaphore must have been previously initialized by the sem_init() function. • The effect of using a semaphore after it has been destroyed is undefined. If you destroy a semaphore that other processes are currently blocked on, they're unblocked, with an error (EINVAL). T90

  35. Return Value • 0 • Success. • -1 • An error occurred (errno is set). T90

More Related