Transcript for:
Understanding the Producer Consumer Problem

Let's see the solution of Producer Consumer Problem. What is Producer Consumer Problem? What is the cause of Producer Consumer Problem? And what are the flaws in Producer Consumer Problem? For this you can check my video where I have fully explained Producer Consumer Problem and how Producer Consumer Problem occurs and what problems are created means inconsistency or loss of data, these are the problems that occur in the Producer Consumer. Here we are solving that Producer Consumer Problem by using the binary semaphore, so let's see the solution. Here I have not mentioned the full code, full code is discussed in Producer Consumer Problem. Here we are talking about solutions how we can solve this through semaphore so that we can achieve the synchronization. Yes, the problem of synchronization in Producer Consumer Problem we are removing it here by using the binary semaphore as well as the counting semaphore. Here I have taken 2 counting semaphore, full and empty. Empty here tells me number of empty slots. Number of empty slots in the buffer. That buffer where we produce data and where consumer consumes data or consumes item. So my number of empty slots is showing empty and number of filled slots, how many slots are already filled that here full counting semaphore tells me, and here one binary semaphore is taken that is S and we initialized it by 1. This is the code of producer, there are other values also but we are just concentrating on the solution, how we can solve it. Down(empty), Down(S), Buffer[IN] we will put item in buffer, In=(In+1)modn, Up(S) and Up(full). So let's solve it one by one. First let's see this case, let's say that here at a point of time because already I have put 3 values here, means in 0, 1, 2 slots there are 3 items a, b, c already put. So here if I talk about empty first so value of empty here is 5 because what is empty? Number of empty slots. So how many total slots do I have in buffer? 8. So out of those 8, 3 slots are filled, so how many are empty? 5. And full, full means number of filled slots. Means how many slots are already filled, I have 3. So if we see at this point of time that my empty are 5 and full are 3 values, so now here if producer comes, let's say producer comes, producer wants to produce 1 item, so what will he do first, to produce item Down(empty), Down(empty) means it wants to use 1 empty slot because he will put 1 item in it. So to use 1 empty slot he will first do Down(empty) here. He will do Down(empty), so value will become what? 4. Then 2nd instruction, just give the numbering like this, 2nd is what? Down(S). Down(S) means value of binary semaphore was made from 1 to 0. so if I write value of S here, value of S is 1. So value of S was initialized to 1, so made from 1 to 0, successfully made value 0, so means it enters that is called a kind of critical section where we are actually executing code. Item p to Buffer[IN], IN is pointing at third location because what does IN show here? Address of that empty slot where we can put the data or item. So here what is the value of slot? 3. So in 3 we put item P, let's say item name is some d. So we put d in third value, third address and In=(In+1)mod n, means value of In was 3, so (3+1)mod 8 because n is what? The number of total slots. My number of total slots is 8, so what comes out? 4mod8 that is 4. Means here we will update In value from 3 to 4. And after that when this code is executed then after that this is exit code. Like this is entry section code and this is my exit section code, means when it exits critical section it will execute this code, what did it execute? Up(S), means semaphore value made again from 0 to 1, why? because we are giving chance or scope to other processes to execute their code so that it should not happen that I did my work and stopped others progress. No, here we want to achieve progress. So how will we achieve it so that I executed my code then I will make semaphore value 1 so that others can also execute. Up(full), did Up(full) means value of full we made 4. 4 means here I have how many number of filled slots? 4. So now here to check consistency there is a simple example, how many empty number of slots? 4, and how many full? 4. So 4 plus 4, 8 and how many total slots I have? 8. Now consumer comes. Consumer comes, consumer wants consume 1 item from this, so where will consumer consume item from? From this buffer. So first what will it execute? Entry section code. We have written 2 lines in entry section code, down(full), down(semaphore). Means first full, how many values are full? 4. We first made 4 down means we made value of full from 4 to 3. And down(S) means value of semaphore we again converted from 1 to 0. Then enters critical section, Buffer[out], what is out value? Out value is 0 means the pointer of out is pointing here, so the item here, which item is there? a, we will consume a, we will put it in item c, the variable and Out=(out+1)mod n, that is value of out which was initialized from 0, we incremented it with 1. Means how we did it? Here value of out is 0 so (0+1)mod8, so 1mod8 is what? 1. So we simply made value of out 1 because an item is already consumed. 1 item is removed from here, so here next where will consumer consume from? From 1. So to run it properly we incremented Out with 1. Now Up of semaphore, Up(S) means we made semaphore value 1 again because after this if producer wants to come again then we have created scope for him that yes, he can also come again. Now, last point is, this is third value, this is fourth instruction, this is the exit code, Up of semaphore we made from 0 to 1, Up(empty), empty means 1 empty slot is increased, if 1 empty slot has increased then we incremented value from 4 to 5. So consumer consumed its thing and left. So we saw a simple example here that if pre-emption is not occurring here, means if producer comes first then consumer comes, or you can run it in reverse, first consumer comes then producer comes without pre-emption, without contact switching if we do it then it works properly, you can see value of empty is how much? 5, value of full is how much? 3, so 5 plus 3 that is 8, so total number of slots I have is 8 and if you look carefully then how many full slots are there? 3 full slots, and how many empty? 1,2,3,4,5. So means this producer consumer code is properly working here if we have only worked sequentially till now means first producer comes, then consumer, or you can also try first consumer or producer. But now we are checking one more example, in which we will try to pre-empt this because where does the major problem come? When processes are executed concurrently. Means when they are executed at the same time then it is very important to synchronize them. That's the point we will see again here. Let's just start with again, the value is again initialized, the value is again 3. Now let's say empty value is 5 and full is 3. Empty value is 5 and full value is 3. Producer came, he first executed Down(empty) means executed first line, to enter critical section it is necessary to execute these two lines, so it did down(empty) means value of empty made from 5 to 4. It made value of empty from 5 to 4, after that it came to this line but if it executes this line means value of semaphore which is again initialized with 1, if it makes this from 1 to 0 then it will enter, then it will again be sequential. So let's try to make it contact switching kind of, means we will pre-empt this, means producer comes first, he made this empty from 5 to 4, but when it was about to do down(S) which here producer becomes pre-empt. Means producer got switched here and who enters? Consumer. Consumer comes. Producer becomes pre-empt here, consumer comes, now when consumer comes, what did he do? down(full), down(full) means he made value of full from 3 to 2. First line he executed down(full) so made value from 3 to 2, did down(S) means made value of semaphore from 1 to 0, enters critical section because here the main point is actually down(S) because out of the two whichever first, out of producer and consumer the one who first does down(S), will down the value of this binary semaphore, he will first enter critical section and who enters critical section, the other one cannot come. How? Let's see. If consumer comes here, consumer did down(full) means made value of full from 3 to 2, and did down(S) means made value of S from 1 to 0, so consumer enters critical section. Now what he has to do? Item C=buffer[out] means what is value of buffer initially? 0. So picked item from 0 location and put it in item here, and out=(out+1), means made value of out from 0 to 1, updated here. Let's see that if consumer is at this point then can producer come here? This was the problem in producer consumer that when one process, either producer or consumer has one process running then in between if some other process, let's say consumer comes at the same time and he executes full and in between if producer again comes then will it create inconsistency here? So here we have to stop this thing. If let's say consumer is now running and in this time system again gets preempt, if again gets preempt then you yourself check that here producer has already executed first line, this line it has already executed, he had made empty from 5 to 4, but can he do down(S)? No, because S value is already 0. If S value means value of semaphore is already 0 then when this tries to do down(S) producer will be blocked here. And that's what we are doing here that if one process is running in between another comes, no problem. But from here again if control goes to the first one then we will stop it here. So that's what we are doing here, we stopped the producer here so that he can't execute or run further, means if he also runs then there will be again the same Producer Consumer inconsistency problem created. So here in case if producer comes then he will simply be blocked so that's why if producer doesn't come then consumer will execute again, consumer is executed upto here, after that Up(S), Up(S) means again he made value of S from 0 to 1. Yes, now there is scope that now producer can execute here Up(empty) value of empty from here again updated from 4 to 5. Now consumer is fully executed here. now consumer is executed then control comes again to whom? Producer. And in producer's PCB it is already saved that he had executed instruction 1, so my control will start from where? Execution will start from where? From 2nd number instruction. This we have already discussed many times before. Did down(S) means it made value of S from 1 to 0. Yes, now it can successfully execute, how will it do? Buffer[IN] means the item that it had to produce, let's say name of that item is d, so he in 3rd location, where is In? what is the value of In? 3, so put d in buffer[3], In=(In+1), what is the in value? 4. In value is made 4 here means producer comes upto here. Now if you want to check, to check you can again check here, let's say that producer gets pre-empt here, consumer comes. If now consumer comes here, it can do down(full), but cannot do down(S) because when it does down(S), S value is already 0, so consumer will be blocked here so he cannot execute critical section code. So this is the little point and this is the logic that when one is running then we try to stop the other one, means we are trying to convert concurrency into serialization in a way by using the semaphores. So here now producer has already run this much, did Up(S) means when it exits, during exiting will again make value of S from 0 to 1 and Up(full), it made value of full up means from 2 to 3. So if you look carefully here, what is the empty value? This has been executed full, consumer is also executed, if you look here, what is the empty value? 5. What is the value of full here? 3. So means consumer consumed one item, which item? which was at 0th location. At 0th location was a, we forgot to remove a from here, so we remove a and value of out is updated here at 1. So if you look carefully, what is value of empty? 5, and value of full is 3, so what is my total value? 8. Means there are 8 number of slots. And if you see in the diagram also, how many slots are filled? 3 slots are filled, 5 slots are empty here. So this is how actually the Producer Consumer Problem works and this is the solution of the Producer Consumer Problem by using the binary semaphore as well as the counting semaphore. You can try to solve this using mutex method also, or you can try to solve this using locking method. So this is all about the solution of the Producer Consumer Problem. Thank you.